Поиск по блогу

среда, 11 февраля 2015 г.

Первый рабочий релиз carmailPrice с результатами парсинга

Спайдер выскреб заготовленые страницы в моем ноутбуке и поместил все в таблицу (3727 строки). Кто бы мог подумать, что у нас продавалось такое количество модификаций автомобилей. Здесь плохоочищеный, но работающий код, и ссылки на итоговые таблицы результатов.

Вот типичный фрагмент выходного потока в консоли

In []:
2015-02-11 18:42:18+0300 [line_price_0_1] DEBUG: Scraped from <200 file:///C:/Users/kiss/Desktop/carsmail/carsmail/cars.mail.ru/cata
log/lamborghini/huracan/i/coupe/index.html>
        {'disel': u'\u0410\u0432\u0442\u043e\u043c\u0430\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0440\u0438\u0432\u043e\u
0434 \u0431\u0435\u043d\u0437\u0438\u043d 3.2 \u0441 \u0434\u043e 100 \u043a\u043c/\u0447',
         'firm': 'lamborghini',
         'line_price': u'11150000',
         'link_to_spec': [u'specifications/index49a3.html?gear_type=204&fuel=222&modification_id=24162'],
         'modification': u'5.2 AT',
         'name_line': u'\u0411\u0430\u0437\u043e\u0432\u0430\u044f',
         'power': u'610',
         'rdate': '2014.12.30',
         'rurl': 'file:///C:/Users/kiss/Desktop/carsmail/carsmail/cars.mail.ru/catalog/lamborghini/huracan/i/coupe/index.html'}

Ниже итоговое сообщение - 3727 строк (записано в C:\Users\kiss\SkyDrive\Docs\mailru\cars_mail_1\carmailPrice\stdout\all_2.csv)

In []:
2015-02-11 18:42:18+0300 [line_price_0_1] INFO: Closing spider (finished)
2015-02-11 18:42:18+0300 [line_price_0_1] INFO: Stored csv feed (3727 items) in: stdout\all_2.csv
2015-02-11 18:42:18+0300 [line_price_0_1] INFO: Dumping Scrapy stats:
        {'downloader/request_bytes': 335244,
         'downloader/request_count': 711,
         'downloader/request_method_count/GET': 711,
         'downloader/response_bytes': 165878910,
         'downloader/response_count': 711,
         'downloader/response_status_count/200': 711,
         'dupefilter/filtered': 78,
         'finish_reason': 'finished',
         'finish_time': datetime.datetime(2015, 2, 11, 15, 42, 18, 642000),
         'item_scraped_count': 3727,
         'log_count/DEBUG': 4441,
         'log_count/INFO': 15,
         'request_depth_max': 2,
         'response_received_count': 711,
         'scheduler/dequeued': 711,
         'scheduler/dequeued/memory': 711,
         'scheduler/enqueued': 711,
         'scheduler/enqueued/memory': 711,
         'start_time': datetime.datetime(2015, 2, 11, 15, 35, 5, 866000)}
2015-02-11 18:42:18+0300 [line_price_0_1] INFO: Spider closed (finished)

C:\Users\kiss\SkyDrive\Docs\mailru\cars_mail_1\carmailPrice>

Вот код спайдера

In [1]:
%load "C:\\Users\\kiss\\SkyDrive\\Docs\\mailru\\cars_mail_1\\carmailPrice\\carmailPrice\\spiders\\price_0_1_1.py"
In []:
import scrapy
from scrapy.contrib.linkextractors import LinkExtractor
from scrapy.contrib.spiders import CrawlSpider, Rule

from carmailPrice.items import CarmailpriceItem
import sys, traceback

class PriceSpider(CrawlSpider):
    name = 'line_price_0_1'
#    allowed_domains = ['cars.mail.ru']
    start_urls = [
#        'http://www.cars.mail.ru/',
#'file:///C:/Users/kiss/Desktop/carsmail/carsmail/cars.mail.ru/catalog/bmw/
#index.html',
    'file:///C:/Users/kiss/Desktop/carsmail/carsmail/index.html',
    ]

#    import ipdb; ipdb.set_trace()
# Rules for selecting URL like this
# 'file:///C:/Users/kiss/Desktop/carsmail/carsmail/cars.mail.ru/catalog/\
#bmw/3/e92/coupe/index.html'
# 'file://C:/Users/kiss/Desktop/carsmail/carsmail/cars.mail.ru/catalog/\
#bmw/index.html'
    rules = (
    Rule(LinkExtractor(allow=('^file:///C:/Users/kiss/Desktop/carsmail/carsmail/cars.mail.ru/catalog/[a-zA-Z0-9_-]+/index.html',),
        deny=(r'^http.*',)), follow=True, ),
##    Rule(LinkExtractor(allow=('^file:///C:/Users/kiss/Desktop/
##    carsmail/carsmail/cars.mail.ru/catalog/[a-zA-Z0-9_-]+/index.html',),
##                           deny=(r'^http.*',)), follow=True, ),
    Rule(LinkExtractor(allow=('^file:///C:/Users/kiss/Desktop/carsmail/carsmail/cars.mail.ru/catalog/([a-zA-Z0-9_-]+/){4,}index.html',),
        deny=(r'^http.*',)), follow=False, callback='parse_item'),
        )

    import ipdb; ipdb.set_trace()
    def parse_item(self, response):

#        in2 = response.xpath('//div[@class="catalog-age__mod__list js-catalog_mod_list"]')
        link_list = response.xpath('.//\
        a[@class="catalog-age__mod__item__equip clear"]')

        items = []

        for link in link_list:
            item = CarmailpriceItem()

            item['modification'] = ''
            item['link_to_spec'] = ''
            item['disel'] = ''
            item['power'] = ''
            item['name_line'] = ''
            item['line_price'] = ''
            item['rurl'] = ''
            item['firm'] = ''
            item['rdate'] = '2014.12.30' 

            try:

    #           Modification ['320d 184hp xDrive AT']
                item['modification'] = link.xpath('.//\
    preceding-sibling::div[@class="catalog-age__mod__item__type clear"]/\
    div[@class="catalog-age__mod__item__type__text catalog-age__mod__item__type__text_title"]/\
    a/text()').extract()

        #       Modification link to URI like this:
        #       https://cars.mail.ru/catalog/bmw/3/f30_31/sedan/specifications/\
        #       ?gear_type=204&amp;fuel=59&amp;modification_id=22939
                item['link_to_spec'] = link.xpath('.//\
        preceding-sibling::div[@class="catalog-age__mod__item__type clear"]/\
        div/a/@href').extract()

        #       Автомат, полный привод, дизель, 7.4 с до 100 км/ч
                item['disel'] = link.xpath('.//\
        preceding-sibling::div[@class="catalog-age__mod__item__note"]/\
        text()').extract()

        #       Power in horses [u'184 \u043b.\u0441.']
                item['power'] = link.xpath('.//\
        preceding-sibling::div[@class="catalog-age__mod__item__type clear"]/\
        div[@class="catalog-age__mod__item__type__text catalog-age__mod__item__type__text_hp"]/\
        text()').extract()

        #       name of line...
        #       <span>Sport Line SKD<span>
                item['name_line'] = link.xpath('.//span[1]/text()').extract()

        #       line Price ['1752000'] from \
        #       <span class="rank"><i>1</i><i>752</i><i>000</i></span>
                item['line_price'] = ''.join(link.xpath('.//div/span/\
                span[@class="rank"]/i/text()').extract())

        #       Response URL = scrapy response html page url
                item['rurl'] = response.url

        #       Try to scrape 'BMW' from URL
                item['firm'] = response.url.split('/')[11]

        #       Do not forget to change the Date
        #        item['rdate'] = '2014.12.30'

            except:
                print 'abrakadabra: ', sys.exc_info()

            items.append(item)
        return items

Особенности краулера

Длинные (решил попробовать) ссылки - это хорошо. И в регулярных выражениях, и в XPath запросах очень жесткая фмльтрация. Длинные ссылки - это плохо. Если на сайте просто добавят новый css-класс в какой нибудь тег..., надо будет все проверять...

На этот последний случай предусмотрены присвоения пустых строк в словаре Item. В случае, если xpath чего-нибудь не спарсит, то на этом месте будет ''.

Сделать позже (ToDo)

Сократить строки RE и XPath. Отформатировать переносы и комментарии. Нстроить rules для онлайна.



Посты чуть ниже также могут вас заинтересовать

1 комментарий:

  1. Забыл упомянуть о pipelines. Там тривиальная чистка кода. Есть пара хороших примеров. Все эти варианты уже можно найти в этом блоге. Так что здесь не публикую

    ОтветитьУдалить