
如题,想保证网络请求一定能获得返回的结果,目前常用写法见下。如果请求语句没报错,就跳出循环,否则反复发送网络请求,直到成功。
有没有更优雅的写法?
样例代码:
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 对面服务器挂了, 你这个就是死循环了, 好一点的办法是捕捉异常之后把失败的 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) |