如题,想保证网络请求一定能获得返回的结果,目前常用写法见下。如果请求语句没报错,就跳出循环,否则反复发送网络请求,直到成功。
有没有更优雅的写法?
样例代码:
import requests
while True:
try:
response = requests.get('http://www.xxxxxxxxx.com')
break
except Exception,e:
print str(e)
print response.status_code
1
lihongjie0209 2018-05-04 15:04:53 +08:00 1
对面服务器挂了, 你这个就是死循环了, 好一点的办法是捕捉异常之后把失败的 url 放到失败队列中, 找个机会重试
|
2
windcode OP @lihongjie0209 这当然是个好的办法,但在这里只想探索下这段代码有没有好的写法
|
3
glacer 2018-05-04 15:19:33 +08:00
装饰器加设置重试
```python def request_retry(times): def decorator(func): def wrapper(*args, **kwargs): while times > 0: try: return func(*args, **kwargs) # 各种异常捕获 except RequestException as e: times -= 1 else: raise HTTPRequestFailedException() # 自定义的异常 return wrapper return decorator ``` |
4
lihongjie0209 2018-05-04 15:22:20 +08:00
@windcode 没有, 网络异常是必然的, 可预见的, 必须加异常处理, 至于怎么处理看业务需求
|
6
glacer 2018-05-04 15:28:26 +08:00
@windcode 回复不支持 markdown 真是蛋疼,缩进都没了,上面的 else 是 while...else,不是 try...except...else。
|
7
Hopetree 2018-05-04 15:40:00 +08:00
timeout 设置一波啊,你用 try 不就想在制定时间得到响应吗,不然用 try 干嘛,要是请求失败要等好久的,所以肯定要设置超时啊
|
8
windcode OP @Hopetree 工程里 timeout 设置了,最大请求次数也设置了,跑起来效率和准确度还行,只是觉得这样一坨代码写的有点丑(笑哭
|
10
hcymk2 2018-05-04 15:51:08 +08:00
可以试下递归。
|
11
zhaoshengzhi 2018-05-04 16:26:19 +08:00
贴一串以前的,用 auto_retry 自动重试,用 time_limit 设置时间限制,也可以组合同时使用
import traceback import json import subprocess import eventlet eventlet.monkey_patch() RETRY_COUNT = 10 TIMEOUT = 10 def time_limit(func, *args, **kwargs): trace = None for _ in range(RETRY_COUNT): try: with eventlet.Timeout(TIMEOUT): return func(*args, **kwargs) except eventlet.timeout.Timeout, e: trace = format_traceback() except: trace = format_traceback() ignore_exception = kwargs.get('ignore_exception') if not ignore_exception: raise Exception( "max retry count=%d, func=%s, argv=%s, trace=%s" % (RETRY_COUNT, func.__name__, (args, kwargs), trace)) def auto_retry(func, *args, **kwargs): trace = None for _ in range(RETRY_COUNT): try: return func(*args, **kwargs) except: trace = format_traceback() ignore_exception = kwargs.get('ignore_exception') if not ignore_exception: raise Exception( "max retry count=%d, func=%s, argv=%s, trace=%s" % (RETRY_COUNT, func.__name__, (args, kwargs), trace)) def format_traceback(): trace = traceback.format_exc() return json.dumps(trace, ensure_ascii=False) |