36

urllib2.request达到超时时,urllib2.URLError会引发异常。重试建立连接的pythonic方法是什么?

4

4 回答 4

65

我会使用重试装饰器。那里还有其他的,但是这个很好用。以下是您可以使用它的方法:

@retry(urllib2.URLError, tries=4, delay=3, backoff=2)
def urlopen_with_retry():
    return urllib2.urlopen("http://example.com")

如果URLError引发,这将重试该功能。检查上面的链接以获取有关参数的文档,但基本上它将重试最多 4 次,每次指数退避延迟加倍,例如 3 秒、6 秒、12 秒。

于 2012-02-25T18:27:00.550 回答
9

有一些图书馆专门研究这个。

一个是backoff,它的设计具有特别的功能敏感性。装饰器被传递任意可调用的返回生成器,这些生成器产生连续的延迟值。最大重试时间为 32 秒的简单指数退避可以定义为:

@backoff.on_exception(backoff.expo,
                      urllib2.URLError,
                      max_value=32)
def url_open(url):
    return urllib2.urlopen("http://example.com")

另一个是重试,它具有非常相似的功能,但是通过预定义的关键字参数指定重试参数的 API。

于 2015-01-31T04:55:10.160 回答
5

要重试超时,您可以按照@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
于 2012-02-25T18:36:52.240 回答
1

对于 Python3:

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/')

如果 backoff_factor 为 0.1,则 :func:.sleep将在重试之间休眠 [0.0s, 0.2s, 0.4s, ...]。它永远不会超过 :attr: Retry.BACKOFF_MAX。urllib3 将休眠::

        {backoff factor} * (2 ** ({number of total retries} - 1))
于 2020-07-27T09:23:07.830 回答