В настоящее время я работаю над проектом парсера, который очень важен для обеспечения правильной обработки КАЖДОГО запроса, т. е. либо для регистрации ошибки, либо для сохранения успешного результата. Я уже внедрил базовый паук, и теперь я могу успешно обрабатывать 99% запросов, но я могу получить такие ошибки, как капча, 50x, 30x или даже недостаточное количество полей в результате (тогда я попробую другой веб-сайт, чтобы найти недостающие поля).
Сначала я подумал, что более «логично» генерировать исключения в обратном вызове синтаксического анализа и обрабатывать их все в errback, это могло бы сделать код более читабельным. Но я пытался только выяснить, что errback может перехватывать только ошибки в модуле загрузчика, такие как статусы ответов, отличные от 200. Если я вызову самореализованный ParseError в обратном вызове, паук просто вызовет его и остановится.
Даже если мне придется обрабатывать запрос на синтаксический анализ непосредственно в обратном вызове, я не знаю, как повторить запрос немедленно в обратном вызове чистым способом. вы знаете, мне, возможно, придется включить другой прокси-сервер, чтобы отправить другой запрос, или изменить какой-либо заголовок запроса.
Я признаю, что я относительно новичок в скраппинге, но я пробовал туда и обратно в течение нескольких дней и до сих пор не могу заставить это работать… Я проверил каждый вопрос на SO, и никто не соответствует, заранее спасибо за помощь. .
ОБНОВЛЕНИЕ: я понимаю, что это может быть очень сложный вопрос, поэтому я пытаюсь проиллюстрировать сценарий в следующем псевдокоде, надеюсь, это поможет:
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