example python scrapy scrapy-spider

example - scrapy python documentation



Scrapy: pausa sin bloqueo (3)

El autor de la pregunta ya proporciona una respuesta en la actualización de la pregunta, pero quiero darle una versión ligeramente mejor para que sea reutilizable para cualquier solicitud.

# removed... from twisted.internet import reactor, defer class MySpider(scrapy.Spider): # removed... def request_with_pause(self, response): d = defer.Deferred() reactor.callLater(response.meta[''time''], d.callback, scrapy.Request( response.url, callback=response.meta[''callback''], dont_filter=True, meta={''dont_proxy'':response.meta[''dont_proxy'']})) return d def parse(self, response): # removed.... yield scrapy.Request(the_url, meta={ ''time'': 86400, ''callback'': self.the_parse, ''dont_proxy'': True }, callback=self.request_with_pause)

Como explicación, Scrapy usa Twisted para administrar la solicitud de forma asíncrona, por lo que necesitamos la herramienta de Twisted para hacer una solicitud retrasada también.

Tengo un problema. Necesito detener la ejecución de una función por un tiempo, pero no detener la implementación del análisis como un todo. Es decir, necesito una pausa sin bloqueo.

Se ve como:

class ScrapySpider(Spider): name = ''live_function'' def start_requests(self): yield Request(''some url'', callback=self.non_stop_function) def non_stop_function(self, response): for url in [''url1'', ''url2'', ''url3'', ''more urls'']: yield Request(url, callback=self.second_parse_function) # Here I need some function for sleep only this function like time.sleep(10) yield Request(''some url'', callback=self.non_stop_function) # Call itself def second_parse_function(self, response): pass

La función non_stop_function debe detenerse por un tiempo, pero no debe bloquear el resto de la salida.

Si inserto time.sleep() , detendrá todo el analizador, pero no lo necesito. ¿Es posible detener una función usando twisted o algo más?

Motivo : Necesito crear una función de no bloqueo que analice la página del sitio web cada n segundos. Allí obtendrá las urls y las llenará durante 10 segundos. Las URL que se hayan obtenido continuarán funcionando, pero la función principal debe estar inactiva.

ACTUALIZACIÓN :

Gracias a TkTech y viach . Una respuesta me ayudó a entender cómo hacer una Request pendiente, y la segunda es cómo activarlo. Ambas respuestas se complementan entre sí e hice una excelente pausa de bloqueo para Scrapy:

def call_after_pause(self, response): d = Deferred() reactor.callLater(10.0, d.callback, Request( ''https://example.com/'', callback=self.non_stop_function, dont_filter=True)) return d

Y usa esta función para mi petición:

yield Request(''https://example.com/'', callback=self.call_after_pause, dont_filter=True)


Si está intentando usar esto para limitar la tasa, probablemente solo quiera usar DOWNLOAD_DELAY lugar.

Scrapy es solo un framework encima de Twisted. En su mayor parte, puede tratarlo igual que cualquier otra aplicación torcida. En lugar de llamar al modo de suspensión, simplemente devuelva la siguiente solicitud para hacer y diga "twisted" para esperar un poco. Ex:

from twisted.internet import reactor, defer def non_stop_function(self, response) d = defer.Deferred() reactor.callLater(10.0, d.callback, Request( ''some url'', callback=self.non_stop_function )) return d


Request objeto de Request tiene un parámetro de callback , intente usar ese para el propósito. Quiero decir, crear un self.second_parse_function que ajusta self.second_parse_function y pause .

Aquí está mi ejemplo sucio y no probado, las líneas cambiadas están marcadas.

class ScrapySpider(Spider): name = ''live_function'' def start_requests(self): yield Request(''some url'', callback=self.non_stop_function) def non_stop_function(self, response): parse_and_pause = Deferred() # changed parse_and_pause.addCallback(self.second_parse_function) # changed parse_and_pause.addCallback(pause, seconds=10) # changed for url in [''url1'', ''url2'', ''url3'', ''more urls'']: yield Request(url, callback=parse_and_pause) # changed yield Request(''some url'', callback=self.non_stop_function) # Call itself def second_parse_function(self, response): pass

Si el enfoque funciona para usted, entonces puede crear una función que construya un objeto Deferred acuerdo con la regla. Se podría implementar de la siguiente manera:

def get_perform_and_pause_deferred(seconds, fn, *args, **kwargs): d = Deferred() d.addCallback(fn, *args, **kwargs) d.addCallback(pause, seconds=seconds) return d

Y aquí es posible su uso:

class ScrapySpider(Spider): name = ''live_function'' def start_requests(self): yield Request(''some url'', callback=self.non_stop_function) def non_stop_function(self, response): for url in [''url1'', ''url2'', ''url3'', ''more urls'']: # changed yield Request(url, callback=get_perform_and_pause_deferred(10, self.second_parse_function)) yield Request(''some url'', callback=self.non_stop_function) # Call itself def second_parse_function(self, response): pass