Python Requests连接异常:是请求超时还是本地网络故障?
问题分析:DNS解析失败导致的连接异常
我怀疑自己的某个端点偶尔会出现超时情况,因此编写了一段Python脚本,每隔30秒循环发送POST请求并打印响应内容:
if __name__ == '__main__': counter = 0 while True: res = requests.post(url, payload) try: response = res.json() except json.JSONDecodeError: response = res.text print(response) if res.status_code != 201: break time.sleep(30) print(res) print(dir(res)) print(res.status_code) print(response)
脚本最终抛出如下异常栈信息:
{'success': True, 'created_on': '2022-09-08 22:42'} # --- 201 response {'success': True, 'created_on': '2022-09-08 22:43'} # --- 201 response Traceback (most recent call last): File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py", line 169, in _new_conn conn = connection.create_connection( File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\util\connection.py", line 73, in create_connection for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\socket.py", line 953, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): socket.gaierror: [Errno 11004] getaddrinfo failed During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 699, in urlopen httplib_response = self._make_request( File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 382, in _make_request self._validate_conn(conn) File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 1010, in _validate_conn conn.connect() File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py", line 353, in connect conn = self._new_conn() File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connection.py", line 181, in _new_conn raise NewConnectionError( urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPSConnection object at 0x000001F5485BB9A0>: Failed to establish a new connection: [Errno 11004] getaddrinfo failed During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\adapters.py", line 439, in send resp = conn.urlopen( File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\connectionpool.py", line 755, in urlopen retries = retries.increment( File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\urllib3\util\retry.py", line 574, in increment raise MaxRetryError(_pool, url, error or ResponseError(cause)) urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='url', port=443): Max retries exceeded with url: /new_lead/5kbLWVNXHQ3U6lJ9trME8hPSf (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x000001F5485BB9A0>: Failed to establish a new connection: [Errno 11004] getaddrinfo failed')) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Users\user\dev\pythonProject\main.py", line 13, in <module> res = requests.post( File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\api.py", line 119, in post return request('post', url, data=data, json=json, **kwargs) File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\api.py", line 61, in request return session.request(method=method, url=url, **kwargs) File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\sessions.py", line 542, in request resp = self.send(prep, **send_kwargs) File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\sessions.py", line 655, in send r = adapter.send(request, **kwargs) File "C:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\adapters.py", line 516, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPSConnectionPool(host='url', port=443): Max retries exceeded with url: /new_lead/5kbLWVNXHQ3U6lJ9trME8hPSf (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x000001F5485BB9A0>: Failed to establish a new connection: [Errno 11004] getaddrinfo failed'))
我的疑问:如果是服务器超时,应该会返回500状态码,脚本也会退出循环并打印响应对象。那这个异常是否意味着我的本地网络断开,导致脚本无法发起请求?
解答
这个异常核心是DNS解析失败,不是服务器超时,也不一定是本地网络完全断开,具体说明:
错误本质
socket.gaierror: [Errno 11004] getaddrinfo failed表示Python调用getaddrinfo函数时无法将目标域名解析为对应的IP地址。这个步骤发生在建立HTTP连接之前,连请求都没发出去,自然不会有服务器返回的响应对象,直接触发连接异常。和服务器超时的区别
- 服务器超时(比如请求发送后长时间没响应)会触发
requests.exceptions.Timeout异常;如果服务器返回5xx状态码,你能正常拿到res对象,脚本会进入状态码判断逻辑。 - 而当前错误是连接建立前的失败,根本没和服务器建立通信。
- 服务器超时(比如请求发送后长时间没响应)会触发
可能的原因
- 本地DNS服务器无法解析目标域名(比如DNS服务临时故障)
- 本地网络的DNS配置错误
- 目标域名的DNS记录临时变更或失效
- 本地网络波动(比如WiFi断连瞬间、网络丢包导致DNS请求失败)
脚本优化建议
给请求增加异常捕获和超时设置,避免脚本直接崩溃,同时记录异常信息:
if __name__ == '__main__': import requests import json import time url = "你的目标URL" payload = {} while True: try: # 设置超时时间,避免无限等待 res = requests.post(url, payload, timeout=10) try: response = res.json() except json.JSONDecodeError: response = res.text print(response) if res.status_code != 201: print(f"收到非201状态码: {res.status_code}") break except requests.exceptions.ConnectionError as e: print(f"连接错误: {str(e)}") # 可以选择继续循环或做其他处理 except requests.exceptions.Timeout as e: print(f"请求超时: {str(e)}") time.sleep(30)
内容的提问来源于stack exchange,提问作者codego
相关产品推荐
相关产品推荐

