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, ...]。如果返回的状态码是 500、502、503 或 504,它也会强制重试。 p>
Retry
的各种其他选项允许更精细的控制:
MaxRetryError
,或者返回带有 3xx 范围。NB:raise_on_status 相对较新,尚未发布 urllib3 或 requests。 raise_on_status 关键字参数似乎最多在 python 3.6 版中进入了标准库。
要在特定 HTTP 状态代码上重试请求,请使用 status_forcelist。例如,status_forcelist=[503] 将重试状态代码 503(服务不可用)。
默认情况下,仅在以下情况下触发重试:
超时错误
HTTPException
引发(来自 Python 3 中的 http.client 或 httplib)。
这似乎是低级 HTTP 异常,例如 URL 或协议(protocol)不是
格式正确。SocketError
协议(protocol)错误
请注意,这些都是阻止接收常规 HTTP 响应的异常。如果生成 any 常规响应,则不进行重试。如果不使用 status_forcelist,即使状态为 500 的响应也不会被重试。
为了使其在使用远程 API 或 Web 服务器时表现得更加直观,我会使用上面的代码片段,它会强制重试状态 500、502 、503 和 504,所有这些在网络上并不少见,并且(可能)在足够大的退避期的情况下可以恢复。
https://stackoverflow.com/questions/15431044/