tutorial source scraping open library example espaƱol crawler python django scrapy twisted celery

python - source - web crawler linux



Scrapy spider no sigue los enlaces cuando usa Apio (1)

Entonces, después de inspeccionar el código de Scrapy y habilitar el registro de Aplery, insertando estas dos líneas en web_spider.py :

from celery.utils.log import get_task_logger logger = get_task_logger(__name__)

Pude localizar el problema: en la función de inicialización de WebSpider :

super(WebSpider, self).__init__(**kw)

La función __init__ del padre CrawlSpider llama a la función _compile_rules que, en suma, copia las reglas de self.rules a self._rules mientras realiza algunos cambios. self._rules es lo que usa la araña cuando busca reglas. Llamar a la función de inicialización de CrawlSpider antes de definir las reglas llevó a un self._rules vacío, por lo tanto, no se siguieron enlaces.

Al mover la línea super(WebSpider, self).__init__(**kw) a la última línea de WebSpider de __init__ solucionó el problema.

Actualización: hay un pequeño error en el código de la respuesta SO anteriormente mencionada . Hace que el reactor se cuelgue después de la segunda llamada. La solución es simple, en el método __init__ WebCrawlerScript , simplemente mueva esta línea:

self.crawler.signals.connect(reactor.stop, signal=signals.spider_closed)

fuera de la declaración if, como se sugiere en los comentarios allí.

Actualización 2: ¡Finalmente conseguí tuberías para trabajar! No fue un problema de apio. Me di cuenta de que el módulo de configuración no se estaba leyendo. Fue simplemente un problema de importación. Arreglarlo:

Establezca la variable de entorno SCRAPY_SETTINGS_MODULE en el módulo de configuración de su proyecto django myproject/settings.py :

import os os.environ[''SCRAPY_SETTINGS_MODULE''] = ''myapp.crawler.crawler.settings''

En el módulo de configuración de Scrapy crawler/settings.py , agregue su ruta de proyecto de sys.path a sys.path para que las importaciones relativas en el archivo de configuración funcionen:

import sys sys.path.append(''/absolute/path/to/scrapy/project'')

Cambie las rutas para adaptarse a su caso.

Estoy escribiendo un rastreador en Python que rastrea todas las páginas en un dominio dado, como parte de un motor de búsqueda específico de un dominio. Estoy usando Django, Scrapy y Apio para lograr esto. El escenario es el siguiente:

Recibo un nombre de dominio del usuario y llamo a la tarea de crawl dentro de la vista, pasando el dominio como argumento:

crawl.delay(domain)

La tarea en sí misma solo llama a una función que inicia el proceso de rastreo:

from .crawler.crawl import run_spider from celery import shared_task @shared_task def crawl(domain): return run_spider(domain)

run_spider inicia el proceso de rastreo, como en esta respuesta SO , reemplazando MySpider con WebSpider .

WebSpider hereda de CrawlSpider y lo estoy usando ahora solo para probar la funcionalidad. La única regla definida toma una instancia SgmlLinkExtractor y una función de devolución de llamada parse_page que simplemente extrae la url de respuesta y el título de la página, rellena un nuevo DjangoItem ( HTMLPageItem ) con ellos y lo guarda en la base de datos (no tan eficiente, lo sé).

from urlparse import urlparse from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor from ..items import HTMLPageItem from scrapy.selector import Selector from scrapy.contrib.spiders import Rule, CrawlSpider class WebSpider(CrawlSpider): name = "web" def __init__(self, **kw): super(WebSpider, self).__init__(**kw) url = kw.get(''domain'') or kw.get(''url'') if not (url.startswith(''http://'') or url.startswith(''https://'')): url = "http://%s/" % url self.url = url self.allowed_domains = [urlparse(url).hostname.lstrip(''www.'')] self.start_urls = [url] self.rules = [ Rule(SgmlLinkExtractor( allow_domains=self.allowed_domains, unique=True), callback=''parse_page'', follow=True) ] def parse_start_url(self, response): return self.parse_page(response) def parse_page(self, response): sel = Selector(response) item = HTMLPageItem() item[''url''] = response.request.url item[''title''] = sel.xpath(''//title/text()'').extract()[0] item.save() return item

El problema es que el rastreador solo rastrea los start_urls y no sigue los enlaces (ni llama a la función de devolución de llamada) cuando sigue este escenario y usa Aplery. Sin embargo, llamar a run_spider través del python manage.py shell funciona muy bien.

Otro problema es que Item Pipelines y logging no funcionan con Apio. Esto está haciendo que la depuración sea mucho más difícil. Creo que estos problemas podrían estar relacionados.