¿Cómo detengo todas las arañas y el motor inmediatamente después de que se cumple una condición en una tubería?

Tenemos un sistema escrito con chatarra para rastrear algunos sitios web. Hay varias arañas y algunas tuberías en cascada para todos los elementos que pasan todos los rastreadores. Uno de los componentes de la canalización consulta a los servidores de Google las direcciones de geoencoding . 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 Google, incluso después de que Google haya respondido con un mensaje de advertencia: “OVER_QUERY_LIMIT”.

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

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

  • Forzar a mi araña áspera para que deje de gatear
from scrapy.project import crawler crawler._signal_shutdown(9,0) #Run this if the cnxn fails. 

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

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

este no funciona en absoluto; los elementos se siguen generando y pasan a la canalización, aunque el registro vomita sys.exit () -> exceptions.SystemExit elevado (sin efecto)

  • ¿Cómo puedo hacer una ruptura de rastreo desechado y salir al encontrar la primera excepción?
 crawler.engine.close_spider(self, 'log message') 

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

Lo intenté:

 scrapy.project.crawler.engine.stop() 

En vano

EDITAR : Si lo hago en la tubería:

desde scrapy.contrib.closespider import CloseSpider

¿Qué debo pasar como el argumento ‘rastreador’ al init () de CloseSpider desde el scope de mi canalización?

Puede elevar una excepción CloseSpider para cerrar una araña. Sin embargo, no creo que esto funcione desde un oleoducto.

EDITAR : avaleske señala en los comentarios a esta respuesta que fue capaz de generar una excepción CloseSpider a partir de una canalización. Lo más sabio sería usar esto.

Una situación similar se ha descrito en el grupo de usuarios de Scrapy, en este hilo.

Yo cito:

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

Podría escribir su propia extensión, mientras observa closespider.py como un ejemplo, que apagará una araña si se cumple una determinada condición.

Otro “truco” 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')