как обрабатывать все виды исключений в проекте scrapy, в errback и обратном вызове ?

В настоящее время я работаю над проектом парсера, который очень важен для обеспечения правильной обработки КАЖДОГО запроса, т. е. либо для регистрации ошибки, либо для сохранения успешного результата. Я уже внедрил базовый паук, и теперь я могу успешно обрабатывать 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
10
задан Shadow Lau 17 June 2012 в 05:46
поделиться