方案一:
from tenacity import retry,wait_fixed,stop_after_attempt
http_retry_wrapper = retry(wait=wait_fixed(6), stop=stop_after_attempt(10),reraise=True)
s = requests.session()
s.request = http_retry_wrapper(s.request)
#或者
x_request = http_retry_wrapper(requests.request)
requests.request()
:
requests
库中的顶层函数,用于发送独立的HTTP请求,它不绑定到特定的Session
对象。requests.request
确实是使用session.request
来发送实际的请求,但它是独立于任何Session
对象的。每次调用requests.request
都会创建一个新的Session
对象,用于该请求,然后销毁它。方案二:
import requests
from requests.adapters import HTTPAdapter,Retry
http_retry_strategy = Retry(total=5, # 最多重试5次
backoff_factor=1,# 重试间隔时间指数增长,每次重试间隔时间是前一次的2倍
method_whitelist=frozenset(['GET', 'POST']), # urllib3默认对post()方法不设置重访问,因此需要我们手动指定才可以
# status_forcelist=[500, 502, 503, 504] # 仅在遇到这些HTTP状态码时重试
)
http_retry_adapter = HTTPAdapter(max_retries=http_retry_strategy)
def x_session():
with requests.Session() as s:
s.mount('http://', http_retry_adapter)
s.mount('https://', http_retry_adapter)
return s
s = x_session()
url="http://www.baidu.com"
resp = s.get(url)
# 处理响应
print(resp.status_code)
在上面的示例中,我们首先创建了一个自定义的重试策略(Retry
对象),然后将该策略应用于一个HTTPAdapter
对象。接着,我们创建了一个requests
会话对象(Session
),并将适配器添加到会话中。最后,我们使用会话对象发送HTTP请求,HTTPAdapter
会根据重试策略自动处理请求的重试。
通过这种方式,你可以自定义重试策略,以适应你的特定需求,并确保请求在遇到错误时能够自动进行重试。
mount
方法的主要用途是配置requests
库的会话对象(Session
),以扩展其功能或自定义其行为。通过挂载自定义的适配器(Adapter
),你可以在会话级别上对HTTP请求进行一些高级控制和定制。以下是mount
方法的使用场景和具体用法:
使用场景:
定制请求行为:你可以为特定的协议(如HTTP和HTTPS)或主机名挂载不同的适配器,以实现不同的请求行为。例如,你可以为特定的域名配置代理服务器,而对其他域名不进行代理。
实现自定义的重试策略:你可以创建一个适配器,配置自定义的重试策略,然后将该适配器挂载到会话对象上。这样,你可以控制请求失败时的重试行为。
连接池控制:通过自定义适配器,你可以配置连接池的大小、连接重用策略等,以优化HTTP请求的性能。
添加自定义的认证机制:如果你需要实现特定的身份验证方式,可以创建适配器来处理认证逻辑,并将其挂载到会话对象上。
定制HTTP头部:你可以挂载一个适配器,以在每个请求中自动添加特定的HTTP头部,如User-Agent等。
根据 urllib3 文档,backoff_factor 是库用来确定重试之间的休眠间隔的基值。
例如,在每次不成功的连接尝试之后,urllib3 将休眠 {backoff_factor} * (2 (总重试次数 - 1)) 秒。
例如,如果 backoff_factor 设置为 0.01,sleep() 将在两次重试之间休眠 0.0s、0.2s、0.4s……。 默认情况下退避是不活动的(设置为 0)。
如果返回的状态码是500、502、503、504,会额外要求重试。 要更好地控制重试,您可以修改重试。
retry_strategy = Retry(
total=5, # 总共重试5次
backoff_factor=1, # 重试之间的等待时间递增因子
status_forcelist=[500, 502, 503, 504], # 遇到这些HTTP状态码时进行重试
)
=============================
其他方案:
A。直接用现成的装饰器:(遇到报错整个test()都会重新执行,而不仅仅是重新发起request,有些情况下,真个test重新执行时,部分外部数据已经变了,使用时要注意)
from retrying import retry
@retry(stop_max_attempt_number=2000)
def test():
url ="www.baidu.com"
result=requests.get(url)
return result.status_code
test()
B、自己手写装饰器
def retry(func):
def wrap(*args, **kwargs):
for _ in range(3):
try:
result = func(*args, **kwargs)
return result
except Exception as e:
print('报错了,重试')
return {}
return wrap
@retry
def make_request(url):
print('以下是发起请求的相关代码')
C、循环语句野路子
def login():
for i in range(10): # 重试10次
try:
resp = requests.get('某某URL')
return resp.json()
except Exception as e:
print(f'请求报错了,重试第{i}次')
continue