iTa*_*ayb 29 python urllib2 decorator
当urllib2.request
到达超时,一个urllib2.URLError
异常.重试建立连接的pythonic方法是什么?
jte*_*ace 58
我会使用重试装饰器.还有其他的,但这个很好用.以下是如何使用它:
@retry(urllib2.URLError, tries=4, delay=3, backoff=2)
def urlopen_with_retry():
return urllib2.urlopen("http://example.com")
Run Code Online (Sandbox Code Playgroud)
如果URLError
引发,这将重试该功能.检查上面的链接以获取有关参数的文档,但基本上它将重试最多4次,每次指数退避延迟加倍,例如3秒,6秒,12秒.
有一些专门从事这方面的图书馆.
一个是退避,其设计具有特别功能的敏感性.装饰器通过任意可调用的返回生成器,产生连续的延迟值.最大重试时间为32秒的简单指数退避可以定义为:
@backoff.on_exception(backoff.expo,
urllib2.URLError,
max_value=32)
def url_open(url):
return urllib2.urlopen("http://example.com")
Run Code Online (Sandbox Code Playgroud)
另一种是重试,它具有非常相似的功能,但是API通过预定义的关键字args指定重试参数.
对于Python3,您可以使用urllib3.Retry
:
from urllib3 import Retry, PoolManager
retries = Retry(connect=5, read=2, redirect=5, backoff_factor=0.1)
http = PoolManager(retries=retries)
response = http.request('GET', 'http://example.com/')
Run Code Online (Sandbox Code Playgroud)
如果 backoff_factor 为 0.1,则 :func:
.sleep
将在重试之间休眠 [0.0s, 0.2s, 0.4s, ...]。它永远不会比 :attr: 长Retry.BACKOFF_MAX
。urllib3 将休眠::Run Code Online (Sandbox Code Playgroud){backoff factor} * (2 ** ({number of total retries} - 1))
要重试超时,您可以按照@Karl Barker 在评论中的建议捕获异常:
assert ntries >= 1
for _ in range(ntries):
try:
page = urlopen(request, timeout=timeout)
break # success
except URLError as err:
if not isinstance(err.reason, socket.timeout):
raise # propagate non-timeout errors
else: # all ntries failed
raise err # re-raise the last timeout error
# use page here
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
25249 次 |
最近记录: |