jak przetwarzać wszelkiego rodzaju wyjątki w projekcie scrapy, w errback i callback?
Obecnie pracuję nad projektem zgarniacza, który jest bardzo ważny, aby zagwarantować, że KAŻDY wniosek zostanie odpowiednio obsłużony, tj. Aby zarejestrować błąd lub zapisać pomyślny wynik. Zaimplementowałem już podstawowego pająka i teraz mogę pomyślnie przetworzyć 99% żądań, ale mogłem uzyskać błędy, takie jak captcha, 50x, 30x, a nawet niewystarczająca liczba pól w wynikach (wtedy spróbuję innej witryny znajdź brakujące pola).
Początkowo uważałem, że bardziej logiczne jest zgłaszanie wyjątków w przetwarzaniu zwrotnym i przetwarzanie ich wszystkich w błąd, co może uczynić kod bardziej czytelnym. Ale próbowałem tylko dowiedzieć się, czy błąd może wychwytywać tylko błędy w module downloadera, takie jak statusy innych niż 200 odpowiedzi. Jeśli podniosę samodzielnie zaimplementowany ParseError w wywołaniu zwrotnym, pająk po prostu podnosi go i zatrzymuje.
Nawet jeśli będę musiał przetworzyć żądanie przetwarzania bezpośrednio w wywołaniu zwrotnym, nie wiem, jak ponowić żądanie natychmiast w wywołaniu zwrotnym w czysty sposób. Wiesz, być może będę musiał dołączyć inny serwer proxy, aby wysłać kolejne żądanie, lub zmodyfikować jakiś nagłówek żądania.
Przyznaję, że jestem stosunkowo nowy w kwestii scrapy, ale próbowałem tam iz powrotem przez wiele dni i wciąż nie mogę tego zrobić… Sprawdziłem każde pytanie dotyczące SO i pojedynczych meczów, z góry dziękuję za pomoc.
AKTUALIZACJA: Zdaję sobie sprawę, że może to być bardzo złożone pytanie, więc staram się zilustrować scenariusz w następującym pseudo kodzie, mam nadzieję, że to pomoże:
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