2010-03-07 17 views
12

Necesito crear una araña/rastreador web configurable por el usuario, y estoy pensando en usar Scrapy. Pero, no puedo codificar los dominios y permitir URL regex: es; esto será configurable en una GUI.Uso de una araña de Scrapy para varios sitios web

¿Cómo puedo (lo más simple posible) crear una araña o un conjunto de arañas con Scrapy donde los dominios y las URL permitidas son configurables dinámicamente? P.ej. Escribo la configuración en un archivo, y la araña lo lee de alguna manera.

+2

@Christian rezar: ¿No era aceptable para las respuestas a su pregunta? – dangra

Respuesta

10

ADVERTENCIA: Esta respuesta fue para Scrapy v0.7, spider manager api ha cambiado mucho desde entonces.

Anulación de clase SpiderManager defecto, cargar sus reglas personalizadas a partir de una base de datos o en otro lugar y instanciate una araña personalizado con sus propias reglas/expresiones regulares y nombre_de_dominio

en MyBot/settings.py:

SPIDER_MANAGER_CLASS = 'mybot.spidermanager.MySpiderManager' 

en MyBot/spidermanager.py:

from mybot.spider import MyParametrizedSpider 

class MySpiderManager(object): 
    loaded = True 

    def fromdomain(self, name): 
     start_urls, extra_domain_names, regexes = self._get_spider_info(name) 
     return MyParametrizedSpider(name, start_urls, extra_domain_names, regexes) 

    def close_spider(self, spider): 
     # Put here code you want to run before spiders is closed 
     pass 

    def _get_spider_info(self, name): 
     # query your backend (maybe a sqldb) using `name` as primary key, 
     # and return start_urls, extra_domains and regexes 
     ... 
     return (start_urls, extra_domains, regexes) 

y ahora la clase de araña costumbre, en MyBot/spider.py:

from scrapy.spider import BaseSpider 

class MyParametrizedSpider(BaseSpider): 

    def __init__(self, name, start_urls, extra_domain_names, regexes): 
     self.domain_name = name 
     self.start_urls = start_urls 
     self.extra_domain_names = extra_domain_names 
     self.regexes = regexes 

    def parse(self, response): 
     ... 

Notas:

  • Puede extender CrawlSpider también si usted desea tomar ventaja de su sistema de reglas
  • para ejecutar un uso araña: ./scrapy-ctl.py crawl <name>, donde name se pasa a SpiderManager.fromdomain y es la clave para recuperar más información spider del sistema backend
  • Como la solución anula el SpiderManager predeterminado, la codificación de una araña clásica (un módulo python por SPIDER) no funciona, pero creo que esto no es un problema para usted.Más información sobre el gestor de arañas por defecto TwistedPluginSpiderManager
+0

La diferencia con el enfoque de Alex Martelli es que las arañas se crean instancias bajo demanda, en lugar de preinstantarlas todas solo para usar una. Este enfoque puede reducir la carga en su backend y la huella de memoria de su proceso bot de scrapy. – dangra

+0

¿Y cómo especifico configuraciones por araña personalizada (ITEM_PIPELINES, USER_AGENT, etc.)? También mencionas './scrapy-ctl.py crawl '. ¿Qué es 'scrapy-ctl.py'? – warvariuc

3

Auto promoción desvergonzada en domo! necesitará crear una instancia del rastreador como se indica en los ejemplos, para su proyecto.

También deberá configurar el rastreador configurable en tiempo de ejecución, que simplemente transfiere la configuración al rastreador y anula la configuración en tiempo de ejecución cuando se cambia la configuración.

4

Lo que necesita es crear dinámicamente clases de araña, la subclasificación de su clase de araña genérica favorita suministrada por scrapy (CrawlSpider subclases con su rules añaden, o XmlFeedSpider, o lo que sea) y la adición de domain_name, start_urls, y posiblemente extra_domain_names (y/o start_requests(), etc.), a medida que los obtiene de su GUI (o archivo de configuración, o lo que sea).

Python hace que sea más fácil realizar dicha creación dinámica de objetos de clase; un ejemplo muy sencillo podría ser:

from scrapy import spider 

def makespider(domain_name, start_urls, 
       basecls=spider.BaseSpider): 
    return type(domain_name + 'Spider', 
       (basecls,), 
       {'domain_name': domain_name, 
       'start_urls': start_urls}) 

allspiders = [] 
for domain, urls in listofdomainurlpairs: 
    allspiders.append(makespider(domain, urls)) 

Esto le da una lista de las mismas clases de araña pelado-hueso - es probable que desee añadir parse métodos a ellos antes de crear una instancia. Sazone al gusto...;-).

+0

y dónde viviría este código? Intenté agregar clases de rastreador de forma dinámica a mis módulos de araña, pero el filtro no los recogió. –

0

Ahora bien, es muy fácil de configurar scrapy para estos fines:

  1. Sobre las primeras direcciones URL para visitar, puede pasar como un atributo en la llamada araña con -a, y utilizar la función start_requests para configurar cómo iniciar la araña

  2. no es necesario configurar la variable allowed_domains para las arañas. Si no incluye esa variable de clase, la araña podrá permitir todos los dominios.

Se debe terminar con algo como:

class MySpider(Spider): 

    name = "myspider" 

    def start_requests(self): 
     yield Request(self.start_url, callback=self.parse) 


    def parse(self, response): 
     ... 

y debe llamar con:

scrapy crawl myspider -a start_url="http://example.com" 
Cuestiones relacionadas