【问题标题】:How to retry IndexError in Scrapy如何在 Scrapy 中重试 IndexError
【发布时间】:2018-10-22 22:48:13
【问题描述】:

有时我得到 IndexError,因为我成功地只抓取了一半的页面,导致解析逻辑得到 IndexError。遇到 IndexError 时如何重试?

理想情况下,它是一个中间件,因此它可以同时处理多个蜘蛛。

【问题讨论】:

  • 能否提供代码示例?

标签: python python-2.7 web-scraping scrapy scrapy-middleware


【解决方案1】:

如果您认为遇到错误需要重新加载页面,您可以尝试:

max_retries = 5

def parse(self, response):
    # to avoid getting stuck in a loop only retry x times
    retry_count = response.meta.get('retry_count', 0)

    item = {}
    try:
        item['foo'] = response.xpath()[123]
        ...
    except IndexError as e:
        if retry_count == max_retries:
            print(f'max retries reached for {response.url}: {e}')
            return
        yield Request(
            response.url, 
            dont_filter=True, 
            meta={'retry_count': retry_count+1}
        )

【讨论】:

  • 最后用中间件是不可能解决的。我的意思是,一个处理多个蜘蛛的中间件
【解决方案2】:

最后,我使用了一个装饰器,并在装饰器函数中从RetryMiddleware 调用_retry() 函数。它运作良好。这不是最好的,最好能够有一个中间件来处理它。但总比没有好。

from scrapy.downloadermiddlewares.retry import RetryMiddleware

def handle_exceptions(function):
    def parse_wrapper(spider, response):
        try:
            for result in function(spider, response):
                yield result
        except IndexError as e:
            logging.log(logging.ERROR, "Debug HTML parsing error: %s" % (unicode(response.body, 'utf-8')))
            RM = RetryMiddleware(spider.settings)
            yield RM._retry(response.request, e, spider)
    return parse_wrapper

然后我像这样使用装饰器:

@handle_exceptions
def parse(self, response):

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多