2

一日一技:方法不对,代码翻倍。Requests如何正确重试?

 11 months ago
source link: https://www.kingname.info/2023/06/11/retry-in-requests/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一日一技:方法不对,代码翻倍。Requests如何正确重试?

2023-06-11

49

548

2 分钟

程序员是一个需要持续学习的群体,如果你发现你现在写的代码跟你5年前的代码没什么区别,说明你掉队了。

我们在做Python开发时,经常使用一些第三方库,这些库很多年来持续添加了新功能。但我发现很多同学在使用这些第三方库时,根本不会使用新的功能。他们的代码跟几年前没有任何区别。

举个例子,使用Request发起HTTP请求,请求失败时,不管什么原因,原地重试最多3次。很多人主要有下面3种写法来重试。

常见的老方法

使用第三方库

这类同学会使用一些专业做重试的第三方库,例如tenacity。详见我的这篇文章:Tenacity——Exception Retry 从此无比简单

手动写装饰器

这类同学会使用装饰器,所以一般会手写装饰器从而复用,例如:

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('以下是发起请求的相关代码')

反复for循环

还有一些同学,写代码走的是野路子:

def login():
for i in range(10): # 重试10次
try:
resp = requests.get('某某URL')
return resp.json()
except Exception as e:
print(f'请求报错了,重试第{i}次')
continue

这类同学基本不会复用代码。代码里面要向N个url发起请求,他们就会在N个地方像上面这样写代码。

这里我虽然说是新方法,但是这个方法应该至少在9年前就能用了。只是网上用的人比较少。我们可以使用requests自带的HTTPAdapter来实现自动重试。当我们不关心具体报错是什么,只需要机械重试时,就可以使用这个方法:

import requests
from requests.adapters import HTTPAdapter, Retry

session = requests.Session()
retries = Retry(total=3, backoff_factor=1)
session.mount('http://', HTTPAdapter(max_retries=retries))
session.mount('https://', HTTPAdapter(max_retries=retries))

# 接下来使用session发起的所有请求,默认最多会重试3次
session.get('http://httpbin.org/delay/5', timeout=2)
session.get('https://www.kingname.info')
...
Buy me a coffee

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK