2013-06-06 9 views
11

Ho creato uno spider e ho collegato un metodo all'evento spider_idle.Scrapy: come inserire manualmente una richiesta da un callback di evento spider_idle?

Come si aggiunge una richiesta manualmente? Non posso semplicemente restituire l'elemento da parse - parse non è in esecuzione in questo caso, poiché tutti gli URL conosciuti sono stati analizzati. Ho un metodo per generare nuove richieste e vorrei eseguirlo dal callback spider_idle per aggiungere le richieste create.

class FooSpider(BaseSpider): 
    name = 'foo' 

    def __init__(self): 
     dispatcher.connect(self.dont_close_me, signals.spider_idle) 

    def dont_close_me(self, spider): 
     if spider != self: 
      return 
     # The engine instance will allow me to schedule requests, but 
     # how do I get the engine object? 
     engine = unknown_get_engine() 
     engine.schedule(self.create_request()) 

     # afterward, ensure we stay alive by raising DontCloseSpider 
     raise DontCloseSpider("..I prefer live spiders.") 

UPDATE: Ho determinato che, probabilmente, mi serve l'oggetto ExecutionEngine, ma io non so esattamente come ottenere che da un ragno, anche se disponibile da un'istanza Crawler.

UPDATE 2: .. grazie. ..crawler è collegato come una proprietà della superclasse, quindi posso semplicemente usare self.crawler senza alcuno sforzo aggiuntivo. >>

risposta

21
class FooSpider(BaseSpider): 
    def __init__(self, *args, **kwargs): 
     super(FooSpider, self).__init__(*args, **kwargs) 
     dispatcher.connect(self.dont_close_me, signals.spider_idle) 

    def dont_close_me(self, spider): 
     if spider != self: 
      return 

     self.crawler.engine.crawl(self.create_request(), spider) 

     raise DontCloseSpider("..I prefer live spiders.") 

Aggiornamento 2016:.

class FooSpider(BaseSpider): 
    yet = False 

    @classmethod 
    def from_crawler(cls, crawler, *args, **kwargs): 
     from_crawler = super(FooSpider, cls).from_crawler 
     spider = from_crawler(crawler, *args, **kwargs) 
     crawler.signals.connect(spider.idle, signal=scrapy.signals.spider_idle) 
     return spider 

    def idle(self): 
     if not self.yet: 
      self.crawler.engine.crawl(self.create_request(), self) 
      self.yet = True 
+0

Ugh. Direttamente una parte della mia superclasse. >.> –

+0

.. Avevo scritto una piccola estensione per collegare il crawler alla classe, ma questo è ovviamente il modo giusto. –

+0

Puoi spiegare cosa fa la funzione sopra. Non ho capito cosa fa ancora. Puoi anche spiegare la differenza da def spider_idle (self): self.crawler.engine.slot.scheduler.next_request() raise DontCloseSpider –

Problemi correlati