【发布时间】:2021-03-31 16:43:51
【问题描述】:
我很好奇在 Python3 中使用 requests 库重复失败请求的最佳实践。我有一个简单的 API 包装器,它向构造的 URL 发出 get 请求。如果requests 引发异常,我想在引发异常之前重试请求。
我不确定是否有一些我不知道的标准做法。我所拥有的会将请求重复 10 倍,将每次迭代中请求之间的等待时间加倍。
import time
import requests
from requests.exceptions import RequestException
def get_request(*args, max_retry=10, **kwargs):
""" Gets requests.models.Response object using requests.get.
Retry request if request fails, with number of iteration specified
by max_retry. """
def recurse_get_request(*args, retries=0, wait=0.005, **kwargs):
try:
return requests.get(*args, **kwargs)
except RequestException as exc:
if retries > max_retry:
raise RequestException from exc
print("Request failed: (%s). Retrying after %s seconds ..." % (exc, "%.2f" % wait))
time.sleep(wait)
# double the wait time after every iteration
wait *= 2
retries += 1
return recurse_get_request(*args, retries=retries, wait=wait, **kwargs)
return recurse_get_request(*args, **kwargs)
get_request('https://sfbay.craigs.org') # bad url
【问题讨论】:
-
加倍请求之间的时间(或一般exponential increase in delay)是我所知道的最佳实践(您也可以添加抖动)。您应该查看 tenacity 库以使用装饰器重试请求。
-
恕我直言,没关系,这是一种标准程序。但是为什么要让它递归而不是 for 循环呢?很难理解发生了什么。我也会尽量延长等待时间。否则在 max_retry=20 时,已经需要 1.5 小时
标签: python python-3.x python-requests urllib