如何让基于urllib.request的JSON API请求程序断网后自动重试?
解决网络断开时程序崩溃的问题:添加自动重试机制
嘿,我明白你的问题了——当网络断开时,你的程序因为没处理异常直接崩溃,想要让它自动重试直到网络恢复对吧?咱们只需要给代码加上异常捕获和循环重试逻辑就能搞定。
问题根源
你的代码里urllib.request.urlopen()在网络不通时会抛出URLError异常,而你没有捕获这个异常,导致程序直接崩溃。另外,还有其他可能的异常(比如API返回非JSON格式、JSON里的键不存在)也需要处理,让程序更健壮。
修改后的完整代码
import urllib.request import urllib.error import json import pprint import sys import winsound import time def data_parser(currency, coin): # 请补上你的API地址,原代码中未定义该变量 url = f"你的API接口地址,例如https://example.com/api/prices?currency={currency}&coin={coin}" while True: try: req = urllib.request.Request(url) r = urllib.request.urlopen(req).read() cont = json.loads(r.decode('utf-8')) kota = float(cont['prices'][currency][coin]) pprint(cont['prices'][currency][coin]) return kota except urllib.error.URLError as e: print(f"网络异常:{e},5秒后重试...") time.sleep(5) except json.JSONDecodeError as e: print(f"API返回无效JSON格式:{e},10秒后重试...") time.sleep(10) except KeyError as e: print(f"JSON结构不符合预期,缺失键:{e},请检查API返回或输入参数!") time.sleep(10) def main(): period = 10 # 先检查命令行参数是否正确传入 if len(sys.argv) != 3: print("用法:python 你的脚本名.py <currency参数> <coin参数>") sys.exit(1) par_1 = sys.argv[1] par_2 = sys.argv[2] # 请补上你定义的蜂鸣频率和时长,原代码中未定义这两个变量 f = 1000 d = 500 while True: print("----") price_1 = data_parser(par_1, par_2) if price_1 > 5.00: winsound.Beep(f, d) time.sleep(period) if __name__ == "__main__": main()
关键改进点说明
- 网络异常捕获:用
except urllib.error.URLError捕获断网、DNS解析失败等网络错误,捕获后打印提示并等待5秒重试 - JSON解析异常:处理API返回内容不是有效JSON的情况,避免程序因格式错误崩溃
- 键缺失异常:如果API返回的JSON结构和预期不符(比如缺少
prices或指定的币种键),会给出明确提示,防止程序崩溃 - 参数检查:在
main函数中先校验命令行参数数量,避免因参数不足导致的错误 - 重试延迟:每次失败后添加延迟,既不会频繁请求给服务器施压,也能减少本地资源占用
注意事项
- 记得补上代码中缺失的
url、f、d变量定义 - 如果遇到
KeyError,大概率是输入参数错误或API返回结构变更,建议先确认问题后再决定是否继续重试 - 你可以根据需求调整重试的延迟时间(比如把5秒改成10秒)
内容的提问来源于stack exchange,提问作者Rial Hammer
相关产品推荐
相关产品推荐

