python - 我可以为 requests.request 设置 max_retries 吗?

Python requests 模块简单而优雅,但有一件事让我很头疼。 有可能得到一个 requests.exception.ConnectionError 并带有如下消息:

Max retries exceeded with url: ...

这意味着请求可以尝试多次访问数据。但是文档中的任何地方都没有提到这种可能性。查看源代码,我没有找到可以更改默认值(大概为 0)的任何地方。

那么是否有可能以某种方式设置请求的最大重试次数?

最佳答案

这不仅会更改 max_retries,还会启用退避策略,使所有 http:// 地址的请求在重试之前休眠一段时间(以共5次):

import requests

from requests.adapters import HTTPAdapter, Retry

s = requests.Session()

retries = Retry(total=5,
                backoff_factor=0.1,
                status_forcelist=[ 500, 502, 503, 504 ])

s.mount('http://', HTTPAdapter(max_retries=retries))

s.get('http://httpstat.us/500')

根据 documentation for Retry : 如果 backoff_factor 是 0.1,那么 sleep() 将在重试之间休眠 [0.05s, 0.1s, 0.2s, 0.4s, ...]。如果返回的状态码是 500502503504,它也会强制重试。 p>

Retry 的各种其他选项允许更精细的控制:

  • total – 允许重试的总次数。
  • connect – 要重试多少个与连接相关的错误。
  • read – 读取错误重试多少次。
  • redirect – 执行多少次重定向。
  • method_whitelist – 我们应该重试的大写 HTTP 方法动词集。
  • status_forcelist – 我们应该强制重试的一组 HTTP 状态代码。
  • backoff_factor – 在尝试之间应用的退避因子。
  • raise_on_redirect – 如果重定向次数用尽,是否引发 MaxRetryError,或者返回带有 3xx 范围。
  • raise_on_status – 与 raise_on_redirect 类似的含义:如果状态在 status_forcelist 范围内并且重试次数已用尽,我们是否应该引发异常或返回响应。

NB:raise_on_status 相对较新,尚未发布 urllib3 或 requests。 raise_on_status 关键字参数似乎最多在 python 3.6 版中进入了标准库。

要在特定 HTTP 状态代码上重试请求,请使用 status_forcelist。例如,status_forcelist=[503] 将重试状态代码 503(服务不可用)。

默认情况下,仅在以下情况下触发重试:

  • 无法从池中获得连接。
  • 超时错误
  • HTTPException 引发(来自 Python 3 中的 http.clienthttplib)。 这似乎是低级 HTTP 异常,例如 URL 或协议(protocol)不是 格式正确。
  • SocketError
  • 协议(protocol)错误

请注意,这些都是阻止接收常规 HTTP 响应的异常。如果生成 any 常规响应,则不进行重试。如果不使用 status_forcelist,即使状态为 500 的响应也不会被重试。

为了使其在使用远程 API 或 Web 服务器时表现得更加直观,我会使用上面的代码片段,它会强制重试状态 500502 503504,所有这些在网络上并不少见,并且(可能)在足够大的退避期的情况下可以恢复。

https://stackoverflow.com/questions/15431044/

相关文章:

linux - sudo bang bang 到底是什么?

list - Pythonic方法返回更大列表中每个第n个项目的列表

python - 使用 python 的 eval() 与 ast.literal_eval()

linux - 如何配置 Qt 以实现从 Linux 到 Windows 目标的交叉编译?

linux - 什么是英特尔微码?

python - 我传入的 Django 请求中的 JSON 数据在哪里?

linux - fork: retry: 资源暂时不可用

linux - 在运行时编辑 shell 脚本

python - 如何在 Django 模板中获取我网站的域名?

python - 词法闭包是如何工作的?