Спайдер выскреб заготовленые страницы в моем ноутбуке и поместил все в таблицу (3727 строки). Кто бы мог подумать, что у нас продавалось такое количество модификаций автомобилей. Здесь плохоочищеный, но работающий код, и ссылки на итоговые таблицы результатов.
Вот типичный фрагмент выходного потока в консоли¶
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)¶
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>
Вот код спайдера¶
%load "C:\\Users\\kiss\\SkyDrive\\Docs\\mailru\\cars_mail_1\\carmailPrice\\carmailPrice\\spiders\\price_0_1_1.py"
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&fuel=59&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 для онлайна.
Посты чуть ниже также могут вас заинтересовать
Забыл упомянуть о pipelines. Там тривиальная чистка кода. Есть пара хороших примеров. Все эти варианты уже можно найти в этом блоге. Так что здесь не публикую
ОтветитьУдалить