uso el enfoque Scrapy Extensions a extender la clase araña a una clase llamada Masterspider que incluye un analizador genérico.
A continuación se muestra la muy "corta" versión de mi analizador ampliado genérico. Tenga en cuenta que deberá implementar un representador con un motor Javascript (como Selenium o BeautifulSoup) a tan pronto como comience a trabajar en las páginas con AJAX. Y una gran cantidad de código adicional para administrar las diferencias entre los sitios (chatarra basada en el título de la columna, manejar URL relativa a larga, administrar diferentes tipos de contenedores de datos, etc.).
Lo que está interesado en el enfoque de Extensión de Scrapy es que aún puede anular el método de analizador genérico si algo no encaja pero nunca tuve que hacerlo. La clase Masterspider comprueba si se han creado algunos métodos (por ejemplo, parser_start, next_url_parser ...) en la clase de araña específica del sitio para permitir la gestión de especificidades: enviar un formulario, construir la solicitud next_url de elementos en la página, etc.
Como estoy rastreando sitios muy diferentes, siempre hay especificidades para administrar. Es por eso que prefiero mantener una clase para cada sitio raspado para que pueda escribir algunos métodos específicos para manejarlo (procesamiento previo/posterior, excepto PipeLines, generadores de solicitud ...).
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/arañas/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
# ...
¿Podría mostrar el código que utiliza para valores fijos de dominio, palabras clave, etiquetas? – jfs
Código agregado. Utiliza BeautifulSoup para analizar el html. – user1284717
hey, no seas demasiado flojo mi amigo. –