python requests.request,python使用requests发送请求
Python请求模块简单优雅,但是有一点让我很困惑。
您可以通过以下消息获得requests . exception . connection error:
url超过最大重试次数:
这意味着请求可以多次尝试访问数据。但是文件中没有任何地方提到这种可能性。看源代码,找不到任何可以更改默认值(0左右)的地方。
那么有没有可能以某种方式设置一个请求的最大重试次数呢?
对2.x的请求有什么更新吗?我很喜欢requests.get(url,max_retries=num_max_retries)的实现。
@ paragbaxi:even better requests . get(URL,max _ retries=num _ max _ retries,dely _ between _ retries=3))
使用urllib3查看我的重试和回退策略的答案。
@WoJ我把你的榜样变成了现实;)just.get和just.post在github.com/kootenpv/just
关于使用请求重试的有用文章:peterbe.com/plog/best-practice-with-retries-with-requests
这不仅会更改max_retries,还会启用回退策略,这将使http://addresses的所有请求在重试之前休眠一段时间(总共5次):
导入请求
从urllib3.util.retry导入重试
从requests.adapters导入HTTPAdapter
s=请求。会话()
重试次数=重试次数(总计=5,
退避因子=0.1,
status_forcelist=[ 500,502,503,504 ])
s.mount(http://,http adapter(max _ retries=retries))
s.get(http://httpstat.us/500 )
根据Retry的文档:如果backoff_factor为0.1,那么sleep()将在重试间隔[0.1s,0.2s,0.4s,].如果返回的状态代码是500、502、503或504,它也将强制重试。
Retry的各种其他选项允许更好的控制:
total-允许的总重试次数。
connect-重试连接相关错误的次数。
read-重试读取错误的次数。
重定向-要执行的重定向次数。
method _ whitelist——我们应该再试一次的大写HTTP方法动词集。
我们应该强制重试的一组HTTP状态代码。
back _ factor-在两次尝试之间应用的后退因子。
raise _ on _ redirect——如果已经用尽了重定向次数,是否将抛出MaxRetryError,或者是否将返回响应代码在3xx范围内的响应。
raise _ on _ status——意思类似于raise_on_redirect:如果状态落在status_forcelist的范围内,并且重试次数已经用尽,我们应该抛出异常还是返回响应?
注意:raise_on_status比较新,还没有发送到urllib3或者请求的版本。strike raise_on_status关键字参数似乎最多进入python版本的标准库。
若要针对特定的HTTP状态代码重试请求,请使用status_forcelist。例如,status_forcelist=[503]将重试状态代码503(服务不可用)。
默认情况下,只有在下列情况下才会触发重试:
无法从池中获取连接。
过时错误
抛出http exception(Python 3中从http.client,否则httplib)。
这似乎是一个低级别的HTTP异常,如URL或协议
形式正确。
SocketError
协议错误
请注意,这些是阻止接收常规HTTP响应的例外情况。如果生成了任何常规响应,将不会重试。如果不使用status_forcelist,即使是状态为500的响应也不会重试。
为了能够以更直观的方式使用远程API或Web服务器,我将使用上面的代码片段,它强制重试状态500、502、503和504,所有这些状态在足够大的回退期间并不常见,并且网络(可能)是可恢复的。
编辑:直接从urllib3导入重试类。
我在尝试实现你的逻辑,但不知道是否正常工作,因为日志只显示一个请求,即使res状态是503。我如何知道重试是否有效?参见代码:pastebin.com/rty4bKTw.
附加的代码按预期工作。是trick status_forcelist参数。这告诉urllib3包重试特定的状态代码。代码:pastebin.com/k2bFbH7Z
Urllib3没有(也不应该)将状态503视为异常(默认情况下)。
这是否适用于非会话操作(例如requests.post())?)
@Connor否,适配器已附加到会话。
Urlib3。重试不再是请求的一部分。这个必须直接导入。建议的编辑
@ user2390183感谢指点,编辑。
重试的是基本的urllib3库。若要设置不同的最大重试次数,请使用备用传输适配器:
从requests.adapters导入HTTPAdapter
s=请求。会话()
s . mount( http://stack overflow . com ,HTTPAdapter(max_retries=5))
Max_retries参数采用整数或Retry()对象;后者允许您对重试失败的类型进行细粒度控制(整数值被转换为仅处理连接失败的Retry()实例;默认情况下,连接后的错误不会被处理,因为这些错误可能会造成影响-)。
旧答案,早于要求的版本1.2.1:
requests库并没有真正做到这一点,这也不是我们想要的(参见这个pull请求)。目前(请求1.1),重试次数设置为0。如果您真的想将其设置为更高的值,则必须进行全局设置:
导入请求
requests . adapters . default _ RETRIES=5
这个常数不被记录;因为将来的版本可能会改变它的处理方式,所以使用它要自担风险。
更新:这个确实变了;在版本1.2.1中,添加了在HTTPAdapter()类上设置max_retries参数的选项,所以现在您必须使用一个备用传输适配器,请参见上文。除非您也修补HTTPAdapter,否则monkey patch方法不再有效。__init__()默认值(非常不推荐)。
如果没有,您不必为每个站点指定此项。您可以执行session.mount (3358 ,http Adapter (max _ retries=10))。这适用于所有HTTP连接。与https相同的功能将适用于所有https连接。
@ user136036:可以,通过匹配最长前缀找到适配器;如果你想把它应用到所有的URL,http://和https://是最少要使用的前缀。请参考与答案链接的文档。
请注意,HTTPAdapter(max_retries=5)只适用于特定场景。请求来自doc,请注意,这仅应用于失败的DNS查找、套接字连接和连接超时,而不会应用于数据已经发送到服务器的请求。默认情况下,请求不会重试失败的连接。要强制重试任何状态码,请参考下面@ datashaman的回答。
@StevenXu:可以,可以配置Retry()来改变重试失败的情况。
小心,Martijn Pieters的回答不适合1.2.1版本。不打补丁库,就不能全局设置。
您可以这样做:
导入请求
从requests.adapters导入HTTPAdapter
s=请求。会话()
s.mount(http://www.github.com ,HTTPAdapter(max_retries=5))
s.mount(https://www.github.com ,HTTPAdapter(max_retries=5))
很好的解决方案,但是请注意重试之间没有延迟。如果你想在尝试之间睡觉,你需要自己做。
在这里对一些答案做了一些工作后,我发现了一个名为backoff的库,它在我的情况下更有效。一个基本的例子:
导入回退
@backoff.on_exception(
后退。博览会,
请求.异常.请求异常,
max_tries=5,
giveup=lambda e: e.response不为None且e.response.status_code为500
)
定义发布(自身,数据):
r=requests.post(url,timeout=10,json=data)
r.raise_for_status()
我还是建议尽快给出站原生函数,但是如果遇到什么问题或者需要更广泛的控制,回退是一个选项。
很棒的图书馆,谢谢!除了请求我还需要这个功能,所以这个很有效!
获得更高控制的更简洁的方法可能是将重试内容打包到一个函数中,并使用装饰器使函数可重复,并将异常列入白名单。
我在这里创造了同样的东西:
复制此链接中的代码:
定义重试(异常,延迟=0,次数=2):
一个装饰器,用于在一组异常的情况下,以指定的延迟重试函数调用
参数列表
-
:param exceptions:需要捕获以进行重试的所有异常的元组
例如,重试(exception_list=(Timeout,Readtimeout))
:param delay:连续重试之间所需的延迟时间(秒)。
:param times:函数应该重试的次数
def outer_wrapper(函数):
@functools.wraps(函数)
def inner_wrapper(*args,**kwargs):
final_excep=无
对于润智中的计数器(次数):
如果计数器0:
时间.睡眠(延迟)
final_excep=无
尝试:
value=function(*args,**kwargs)
返回值
除了(例外情况)e:
final _ excep=e
通过#或记录它
如果最终_例外不为无:
提高最终_超越
返回内部包装
返回外层包装
@ retry(exceptions=(TimeoutError,ConnectTimeoutError),delay=0,times=3)
定义call_api():
当页面为"无"时:
尝试:
page=requests.get(url,timeout=5,proxies=proxies)
例外情况除外:
页面=无
说实话,你错过了问题的重点。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。