Я использую Scrapy Extensions подход к , расширяющий класс Spider до класса с именем Masterspider, который включает в себя универсальный парсер.
Ниже приведена очень "короткая" версия моего расширенного синтаксического анализатора. Обратите внимание, что вам нужно реализовать средство визуализации с движком Javascript (например, Selenium или BeautifulSoup) a, как только вы начнете работать со страницами, используя AJAX. И много дополнительного кода для управления различиями между сайтами (сбор данных на основе заголовка столбца, обработка относительных и длинных URL-адресов, управление различными типами контейнеров данных и т. Д.).
Что интересно в подходе Scrapy Extension, так это то, что вы все равно можете переопределить универсальный метод синтаксического анализатора, если что-то не подходит, но мне это никогда не приходилось. Класс Masterspider проверяет, были ли созданы некоторые методы (например, parser_start, next_url_parser ...) в классе паука, специфичном для сайта, чтобы разрешить управление спецификациями: отправить форму, создать запрос next_url из элементов на странице и т. Д. 1013 *
Поскольку я перебираю очень разные сайты, всегда есть особенности для управления. Вот почему я предпочитаю сохранять класс для каждого очищенного сайта, чтобы я мог написать некоторые конкретные методы для его обработки (предварительная / постобработка, кроме PipeLines, Генераторы запросов ...).
masterspider / SiteSpider / settings.py
EXTENSIONS = {
'masterspider.masterspider.MasterSpider': 500
}
masterspider / masterspdier / masterspider.py
# -*- coding: utf8 -*-
from scrapy.spider import Spider
from scrapy.selector import Selector
from scrapy.http import Request
from sitespider.items import genspiderItem
class MasterSpider(Spider):
def start_requests(self):
if hasattr(self,'parse_start'): # First page requiring a specific parser
fcallback = self.parse_start
else:
fcallback = self.parse
return [ Request(self.spd['start_url'],
callback=fcallback,
meta={'itemfields': {}}) ]
def parse(self, response):
sel = Selector(response)
lines = sel.xpath(self.spd['xlines'])
# ...
for line in lines:
item = genspiderItem(response.meta['itemfields'])
# ...
# Get request_url of detailed page and scrap basic item info
# ...
yield Request(request_url,
callback=self.parse_item,
meta={'item':item, 'itemfields':response.meta['itemfields']})
for next_url in sel.xpath(self.spd['xnext_url']).extract():
if hasattr(self,'next_url_parser'): # Need to process the next page URL before?
yield self.next_url_parser(next_url, response)
else:
yield Request(
request_url,
callback=self.parse,
meta=response.meta)
def parse_item(self, response):
sel = Selector(response)
item = response.meta['item']
for itemname, xitemname in self.spd['x_ondetailpage'].iteritems():
item[itemname] = "\n".join(sel.xpath(xitemname).extract())
return item
masterspider / SiteSpider / пауки / somesite_spider.py
# -*- coding: utf8 -*-
from scrapy.spider import Spider
from scrapy.selector import Selector
from scrapy.http import Request
from sitespider.items import genspiderItem
from masterspider.masterspider import MasterSpider
class targetsiteSpider(MasterSpider):
name = "targetsite"
allowed_domains = ["www.targetsite.com"]
spd = {
'start_url' : "http://www.targetsite.com/startpage", # Start page
'xlines' : "//td[something...]",
'xnext_url' : "//a[contains(@href,'something?page=')]/@href", # Next pages
'x_ondetailpage' : {
"itemprop123" : u"id('someid')//text()"
}
}
# def next_url_parser(self, next_url, response): # OPTIONAL next_url regexp pre-processor
# ...