2012-03-14 14 views
9

Tenemos un sistema escrito con scrapy para rastrear algunos sitios web. Hay varias arañas, y pocas tuberías en cascada para todos los elementos pasados ​​por todos los rastreadores. Uno de los componentes de la interconexión consulta los servidores de Google para las direcciones de geocodificación. Google impone un límite de 2500 solicitudes por día por dirección IP, y amenaza con prohibir una dirección IP si continúa consultando a Google incluso después de que Google haya respondido con un mensaje de advertencia: 'OVER_QUERY_LIMIT'.¿Cómo detengo todas las arañas y el motor inmediatamente después de que se cumple una condición en una tubería?

Por lo tanto, quiero saber acerca de cualquier mecanismo que pueda invocar desde el interior de la tubería que detenga por completo todo el rastreo/procesamiento de todas las arañas y también el motor principal.

He comprobado otras preguntas similares y sus respuestas no han funcionado:

from scrapy.project import crawler 
crawler._signal_shutdown(9,0) #Run this if the cnxn fails. 

esto no funciona ya que toma tiempo para la araña para detener ejecución y, por tanto, muchas más solicitudes se realizan a google (que podría bloquear mi dirección IP)

import sys 
sys.exit("SHUT DOWN EVERYTHING!") 

éste no funciona en absoluto; artículos son continuamente generan y se transmiten a la tubería, aunque el registro vomita sys.exit() -> exceptions.SystemExit elevada (o ningún efecto)

crawler.engine.close_spider(self, 'log message') 

este tiene el mismo problema que el primer caso mencionado anteriormente.

me trataron:

scrapy.project.crawler.engine.stop() 

En vano

EDITAR: Si lo hago en la tubería:

de importación scrapy.contrib.closespider CloseSpider

¿qué debo pasar como el argumento 'rastreador' al init () (del alcance de mi canalización de CloseSpider?

Respuesta

12

Puedes raise a CloseSpider exception cerrar una araña. Sin embargo, no creo que esto funcione desde una tubería.

EDIT: notas de avaleske en los comentarios a esta respuesta que fue capaz de plantear una excepción de CloseSpider de una tubería. Lo más sabio sería usar esto.

Una situación similar se ha descrito en el grupo Usuarios Scrapy, in this thread.

cito:

Para cerrar una araña para cualquier parte de su código se debe utilizar engine.close_spider método. Ver esta extensión para un uso ejemplo: https://github.com/scrapy/scrapy/blob/master/scrapy/contrib/closespider.py#L61

Se puede escribir su propia extensión, mientras busca en closespider.py como ejemplo, que se cerrará una araña si una determinada condición se ha cumplido.

Otro "pirateo" sería establecer una bandera en la araña en la tubería. Por ejemplo:

tubería:

def process_item(self, item, spider): 
    if some_flag: 
     spider.close_down = True 

araña:

def parse(self, response): 
    if self.close_down: 
     raise CloseSpider(reason='API usage exceeded') 
+0

Gracias por el puesto. Me imagino que esto cerrará la araña como el primer ejemplo que se muestra arriba, pero lleva tiempo y algunos elementos de cada araña programada pasarán por la tubería. Lo que significa que cientos de consultas se realizarán en Google una vez que se haya recibido la advertencia ... ¿Cómo MATARé todo? ¡Si no puede haber una manera en absoluto, usaré el "truco"! ¡¡¡Muchas gracias!!! – aniketd

+0

También la clase CloseSpider toma un argumento 'rastreador'. En mi canalización y su alcance ¿qué objeto se debe pasar? – aniketd

+1

No estoy muy seguro de a qué se refiere; pero este documento sobre extensiones podría ayudar: http://doc.scrapy.org/en/latest/topics/extensions.html y el documento sobre las tuberías: http://doc.scrapy.org/en/latest/topics/item -pipeline.html. Pasaría la araña a la tubería, pondría la bandera allí y lanzaría una excepción CloseSpider en la propia araña. –

Cuestiones relacionadas