Ejecutando tareas de Scrapy en Python

Mi secuencia de comandos de Scrapy parece funcionar bien cuando lo ejecuto en escenarios ‘únicos’ desde la línea de comandos, pero si bash ejecutar el código dos veces en la misma sesión de Python, aparece este error:

“ReactorNotRestartable”

¿Por qué?

El código ofensivo (última línea arroja el error):

crawler = CrawlerProcess(settings) crawler.install() crawler.configure() # schedule spider #crawler.crawl(MySpider()) spider = MySpider() crawler.queue.append_spider(spider) # start engine scrapy/twisted crawler.start() 

Cerca de la respuesta de Joël, pero quiero elaborar un poco más de lo que es posible en los comentarios. Si observa el código fuente del rastreador , verá que la clase CrawlerProcess tiene un start , pero también una función de stop . Esta función de stop se encarga de limpiar las partes internas del rastreo para que el sistema termine en un estado desde el cual pueda comenzar de nuevo.

Por lo tanto, si desea reiniciar el rastreo sin abandonar el proceso, llame a crawler.stop() en el momento adecuado. Más adelante, simplemente llame a crawler.start() nuevamente para reanudar las operaciones.

Edición: en retrospectiva, esto no es posible (debido al reactor retorcido, como se menciona en una respuesta diferente); La stop solo se encarga de una terminación limpia. Mirando hacia atrás en mi código, tuve un contenedor para los procesos del rastreador. A continuación puede encontrar algo de código (redactado) para que funcione con el módulo de multiprocesamiento de Python. De esta manera puede reiniciar más fácilmente los rastreadores. (Nota: Encontré el código en línea el mes pasado, pero no incluí la fuente … así que si alguien sabe de dónde viene, actualizaré los créditos de la fuente).

 from scrapy import project, signals from scrapy.conf import settings from scrapy.crawler import CrawlerProcess from scrapy.xlib.pydispatch import dispatcher from multiprocessing.queues import Queue from multiprocessing import Process class CrawlerWorker(Process): def __init__(self, spider, results): Process.__init__(self) self.results = results self.crawler = CrawlerProcess(settings) if not hasattr(project, 'crawler'): self.crawler.install() self.crawler.configure() self.items = [] self.spider = spider dispatcher.connect(self._item_passed, signals.item_passed) def _item_passed(self, item): self.items.append(item) def run(self): self.crawler.crawl(self.spider) self.crawler.start() self.crawler.stop() self.results.put(self.items) # The part below can be called as often as you want results = Queue() crawler = CrawlerWorker(MySpider(myArgs), results) crawler.start() for item in results.get(): pass # Do something with item 

crawler.start() inicia Twisted reactor. Sólo puede haber un reactor.

Si quieres correr más arañas – usa

 another_spider = MyAnotherSpider() crawler.queue.append_spider(another_spider) 

He usado hilos para iniciar el reactor varias veces en una aplicación y evitar el error ReactorNotRestartable.

Hilo (target = process.start) .start ()

Aquí está la explicación detallada: Ejecutar una araña de Scrapy en una tarea de apio

Me parece que no puede usar el crawler.start() dos veces: es posible que tenga que volver a crearlo si desea que se ejecute una segunda vez.