Wie verarbeite ich alle Arten von Ausnahmen in einem Scrapy-Projekt, in Errback und Callback?

Ich arbeite derzeit an einem Scraper-Projekt, das sehr wichtig ist, um sicherzustellen, dass JEDE Anforderung ordnungsgemäß verarbeitet wird, d. H. Um einen Fehler zu protokollieren oder ein erfolgreiches Ergebnis zu speichern. Ich habe den Basic Spider bereits implementiert und kann jetzt 99% der Anfragen erfolgreich bearbeiten, aber ich könnte Fehler wie Captcha, 50x, 30x oder sogar nicht genügend Felder im Ergebnis bekommen (dann versuche ich es mit einer anderen Website) finden Sie die fehlenden Felder).

Zuerst dachte ich, dass es "logischer" ist, Ausnahmen im Parsing-Callback auszulösen und sie alle in Errback zu verarbeiten. Dies könnte den Code lesbarer machen. Aber ich habe nur versucht herauszufinden, dass errback nur Fehler im Downloader-Modul abfangen kann, wie z. B. Nicht-200-Antwortstatus. Wenn ich im Callback einen selbst implementierten ParseError auslöse, löst der Spider diesen einfach aus und stoppt.

Auch wenn ich die Parsing-Anfrage direkt im Rückruf verarbeiten muss, weiß ich nicht, wie ich die Anfrage sofort im Rückruf sauber wiederholen kann. u wissen, muss ich möglicherweise einen anderen Proxy einschließen, um eine andere Anforderung zu senden, oder einige Anforderungsheader ändern.

Ich gebe zu, dass ich relativ neu in Scrapy bin, aber ich habe es seit Tagen hin und her versucht und kann es immer noch nicht zum Laufen bringen. Ich habe jede einzelne Frage zu SO überprüft und niemand passt, danke im Voraus für die Hilfe.

UPDATE: Mir ist klar, dass dies eine sehr komplexe Frage sein kann. Ich versuche daher, das Szenario im folgenden Pseudocode zu veranschaulichen. Ich hoffe, dies hilft:

from scraper.myexceptions import *

def parseRound1(self, response):

    .... some parsing routines ...
    if something wrong happened:
       # this causes the spider raises a SpiderException and stops
       raise CaptchaError
    ...

    if no enough fields scraped:
       raise ParseError(task, "no enough fields")
    else:
       return items

def parseRound2(self, response):
    ...some other parsing routines...

def errHandler(self, failure):
    # how to trap all the exceptions?
    r = failure.trap()
    # cannot trap ParseError here
    if r == CaptchaError:
       # how to enqueue the original request here?
       retry
    elif r == ParseError:
        if raised from parseRound1:
            new request for Round2
        else:
            some other retry mechanism
    elif r == HTTPError:
       ignore or retry

Antworten auf die Frage(2)

Ihre Antwort auf die Frage