如何在Python脚本中增大DNS解析超时并配置重试机制
Python DNS解析超时与重试逻辑修改方案
socket.settimeout()是单个socket实例的方法,无法直接作用于socket.getaddrinfo()的DNS解析流程,要配置全局DNS解析超时,需要使用socket.setdefaulttimeout(value)设置全局默认socket超时阈值,该配置会覆盖所有socket相关操作(包括DNS解析、连接建立等)的超时时间。
修改后可直接运行的代码
import socket import http.client # 全局设置所有socket操作超时为30秒,包含DNS解析流程 socket.setdefaulttimeout(30) # 域名解析校验,同时捕获解析错误与超时异常 def dns_lookup(host): try: socket.getaddrinfo(host, 80) except (socket.gaierror, socket.timeout): return False return True # 网站爬取逻辑,复用全局30秒超时配置 def request_website_data(): conn = http.client.HTTPConnection("google.com") conn.request("GET", "/") res = conn.getresponse() if res.status == 200: print("Connection to the website worked! Do some more stuff...") else: print(f"Connection failed with status code: {res.status}") conn.close() # 最多重试5次解析 max_retry = 5 for attempt in range(max_retry): print(f"Start DNS resolution attempt {attempt + 1}/{max_retry}") dns_res = dns_lookup('google.com') if dns_res: request_website_data() break print(f"DNS resolution failed on attempt {attempt + 1}") else: # 循环正常走完(未触发break)代表5次尝试全部失败 print("All 5 DNS resolution attempts failed, program terminated.")
关键修改点说明
- 导入模块后第一行设置全局30秒超时,不需要给单个socket重复配置
- 扩展
dns_lookup的异常捕获范围,同时捕获解析失败(socket.gaierror)和解析超时(socket.timeout)两类异常,避免超时抛出未捕获错误导致程序直接崩溃 - 重试循环增加
else分支,5次重试全部耗尽时给出明确终止提示 - 爬取函数增加连接关闭逻辑,避免连接泄漏
- 全局超时配置会自动作用于
HTTPConnection的连接、请求阶段,即使请求阶段触发二次DNS解析也会遵守30秒超时规则
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

