【问题标题】:Prevent ignoring non 200 response status - Scrapy防止忽略非 200 响应状态 - Scrapy
【发布时间】:2020-10-31 16:08:03
【问题描述】:

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

忽略非 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,但蜘蛛在失败1 次后忽略了502 状态。重现问题this link 总是返回 502 状态码。 我在设置中启用了我的自定义中间件:

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

【问题讨论】:

  • 你应该return super()... 而不是return response

标签: python web-scraping scrapy web-crawler http-status-code-502


【解决方案1】:

根据the docs,您的请求应该已经被 RetryMiddleware 重试了两次。在我看来,这也可以从你的日志中看出,因为你有两次Crawled (xxx) &lt;GET http://sample.com/&gt;(一次是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,可以在您的蜘蛛中使用define a list of error codes that your spider can handle 属性handle_httpstatus_list。如果您想在蜘蛛中处理请求,即使它失败了 k 次,这也会很有用。

class MySpider(CrawlSpider):
    handle_httpstatus_list = [404]

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

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

【讨论】:

  • 你是完全正确的并且显示了有用的点,但问题是当我使用内置中间件时它工作正常,重试 4 次后它放弃重试但是当我使用自定义中间件时我编写并添加了有问题的更新,它只重试了 1 次,然后由于未知原因而忽略。
猜你喜欢
  • 2017-10-31
  • 2014-11-23
  • 1970-01-01
  • 2018-02-03
  • 2019-11-27
  • 1970-01-01
  • 1970-01-01
  • 2015-02-02
  • 1970-01-01
相关资源
最近更新 更多