0

我正在抓取一个网站,我想在获得响应状态 50x 时重试请求,但我得到了

忽略非 200 响应

我怎样才能摆脱它并重试请求几次(例如默认为 3 次)或重试直到获得 200 响应状态。

DEBUG:scrapy.downloadermiddlewares.retry:Retrying <GET http://sample.com/> (failed 1 times): 502 Bad Gateway
DEBUG:scrapy.core.engine:Crawled (502) <GET http://sample.com/> (referer: None)
CRITICAL:security_daily_history:<twisted.python.failure.Failure scrapy.spidermiddlewares.httperror.HttpError: Ignoring non-200 response>

更新:

我的自定义重试中间件是:

class CustomRetryMiddleware(RetryMiddleware):

    def process_response(self, request, response, spider):
        super().process_response(request, response, spider)
        return response

它应该像内置一样工作,RetryMiddleware但它没有,我RETRY_TIMES = 4在我的设置中设置但蜘蛛502在失败 1 次后忽略状态。要重现此问题,此链接始终返回 502 状态代码。我通过以下方式启用了我的自定义中间件:

DOWNLOADER_MIDDLEWARES = {
   'scrapy.downloadermiddlewares.retry.RetryMiddleware': None,
   'projectname.middlewares.CustomRetryMiddleware': 543,
}
4

1 回答 1

2

根据文档,您的请求应该已经被 RetryMiddleware 重试了两次。在我看来,这也可以从您的日志中看出,因为您Crawled (xxx) <GET http://sample.com/>在那里有两次(一次是 502,一次是 200)`

您可以在请求中使用属性调整重试次数:

也可以使用 Request.meta 的 max_retry_times 属性为每个请求指定最大重试次数。初始化时,max_retry_times 元键优先于 RETRY_TIMES 设置。

现在没有尝试过,但是当您创建并产生原始请求时,这应该看起来像这样:

request_with_cookies = Request(
    url='http://www.example.com', meta={'max_retry_times': 10})

然后,该请求http://www.example.com将重试最多 10 次。

如果请求经常失败,您的请求将被忽略scrapy.spidermiddlewares.httperror.HttpErrorMiddleware(参见您的日志消息)。

根据scrapy docs,可以定义蜘蛛可以使用蜘蛛中的属性处理的错误代码列表handle_httpstatus_list。如果你想在你的蜘蛛中处理请求,即使它失败了 k 次,这将很有用。

class MySpider(CrawlSpider):
    handle_httpstatus_list = [404]

在这种特定情况下,由于您遇到 502 错误,因此您希望使用handle_httpstatus_list = [502](仅当您真的想处理它时,但我想您想要的是调整 RetryMiddleware 中的重试次数?)。

在返回成功代码之前,我在文档中看不到运行请求的可能性。这是有道理的,因为它会在抓取过程中引入无限循环。如果要重试直到返回成功代码,只需将重试次数设置为非常高的数字,例如max_retry_times = 100. 如果100次后没有成功,它很可能不会很快改变。

于 2020-11-01T07:54:16.097 回答