2017-07-17 5 views
2

Ich habe eine Spinne, die URL aus einer Wiedergabeliste nimmt.Scrapy schließen Spinne, wenn keine URLs zum Crawlen

Ich möchte Spider schön schließen, wenn keine URL gefunden wird. Ich habe versucht, CloseSpider Ausnahme zu implementieren, aber es scheint, dass es diesen Punkt nicht

def start_requests(self): 
    while True: 
     item = json.loads(self.__pop_queue()) 
     if not item: 
      raise CloseSpider("Closing spider because no more urls to crawl") 
     try: 
      yield scrapy.http.Request(item['product_url'], meta={'item': item}) 
     except ValueError: 
      continue 

Auch nicht erreicht, obwohl ich die CloseSpider Ausnahme bin erhöhen, aber ich bin immer noch die folgenden Fehler bekommen:

[email protected]:/scrapper# scrapy crawl general -a country=my -a log=file 
2017-07-17 12:05:13 [scrapy.core.engine] ERROR: Error while obtaining start requests 
Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/site-packages/scrapy/core/engine.py", line 127, in _next_request 
    request = next(slot.start_requests) 
    File "/scrapper/scrapper/spiders/GeneralSpider.py", line 20, in start_requests 
    item = json.loads(self.__pop_queue()) 
    File "/usr/local/lib/python2.7/json/__init__.py", line 339, in loads 
    return _default_decoder.decode(s) 
    File "/usr/local/lib/python2.7/json/decoder.py", line 364, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
TypeError: expected string or buffer 

Außerdem , Ich habe auch versucht, TypeError in der gleichen Funktion zu fangen, aber es funktioniert auch nicht.

Gibt es empfohlen, diese

Dank

Antwort

4

Sie müssen behandeln überprüfen, ob self.__pop_queue() kehrt etwas, bevor Sie es zu json.loads() geben (oder fangen die TypeError beim Aufruf es), so etwas wie:

def start_requests(self): 
    while True: 
     item = self.__pop_queue() 
     if not item: 
      raise CloseSpider("Closing spider because no more urls to crawl") 
     try: 
      item = json.loads(item) 
      yield scrapy.http.Request(item['product_url'], meta={'item': item}) 
     except (ValueError, TypeError): # just in case the 'item' is not a string or buffer 
      continue 
+0

Nizza Art und Weise, es zu tun, dank –

+0

@BLANQUERAdrien - Aufstieg eine Frage der eigenen und posten Sie Ihren Code/Fehler und wir werden sehen, was los ist, das ist mehr auf das OP-Problem zugeschnitten, indem man elegant seine Generatorfunktion beendet. – zwer

+0

@zwer Danke es funktioniert jetzt wie erwartet. Eine Sache, über die ich immer noch verwirrt bin. An welchem ​​Punkt können wir die Spinnenausnahmen fangen. Ich meine in Bezug auf Scrapy Framework was ist der Standard? Danke –

1

Ich hatte das gleiche Problem und fand einen kleinen Trick. Wenn die Spinne in im Leerlauf ist (wenn es nichts tut), überprüfe ich, ob noch etwas in der Redis-Warteschlange übrig ist. Wenn nicht, schließe ich die Spinne mit close_spider. Der folgende Code in der spider Klasse befindet:

@classmethod 
def from_crawler(cls, crawler, *args, **kwargs): 
    from_crawler = super(SerpSpider, 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 self.q.llen(self.redis_key) <= 0: 
     self.crawler.engine.close_spider(self, reason='finished') 
+0

Dies ist informativ bro. Havent hat Signale noch benutzt. Vielen Dank –

Verwandte Themen