socket.getaddrinfo解析正常但requests报dns_unresolved_hostname求助
问题:socket可解析hosts域名但requests模块报dns_unresolved_hostname错误
现象复现
在Windows Server 2019的工具服务器上执行以下代码:
>>> import requests >>> import socket >>> print(socket.getaddrinfo('myurl.test', 1414)) [(<AddressFamily.AF_INET: 2>, 0, 0, '', ('10.140.11.11', 1414))] >>> url ='http://myurl.test:1414/testing' >>> body = '{"dateTime": "2022-07-11T16:45:52.633840","testcase": "1"}' >>> h = {'Content-Type': 'application/json',} >>> response = requests.post(url, data=body, headers = h) >>> response.text '<HTML><HEAD>\r\n <TITLE>Network Error</TITLE>\r\n </HEAD>\r\n <BODY>\r\n <FONT face="Helvetica">\r\n <big><strong></strong></big><BR>\r\n </FONT>\r\n <blockquote>\r\n <TABLE border=0 cellPadding=1 width="80%">\r\n <TR><TD>\r\n <FONT face="Helvetica">\r\n <big>Network Error (dns_unresolved_hostname)</big>\r\n <BR>\r\n <BR>\r\n </FONT>\r\n </TD></TR>\r\n <TR><TD>\r\n <FONT face="Helvetica">\r\n Your requested host "myurl.test" could not be resolved by DNS.\r\n </FONT>\r\n </TD></TR>\r\n <TR><TD>\r\n <FONT face="Helvetica">\r\n \r\n </FONT>\r\n </TD></TR>\r\n <TR><TD>\r\n <FONT face="Helvetica" SIZE=2>\r\n <BR>\r\n For assistance, contact your network support team.\r\n </FONT>\r\n </TD></TR>\r\n </TABLE>\r\n </blockquote>\r\n </FONT>\r\n </BODY></HTML>\r\n'
socket.getaddrinfo可通过hosts文件解析出正确IP和端口,但requests.post返回dns_unresolved_hostname错误- 命令行
curl请求该URL正常 - 另一测试服务器上执行相同Python逻辑(端点略有不同)正常
- 部分用户执行上述步骤可获得有效响应
已排查hosts文件、代理设置及环境变量,未发现异常。
排查与解决建议
1. 强制requests使用socket的解析结果
requests底层依赖的urllib3可能采用了与socket不同的DNS解析逻辑,可手动替换解析函数,强制使用socket的解析结果:
import requests import socket from urllib3.util import connection def custom_create_connection(host, port, *args, **kwargs): # 复用socket的解析结果 addrinfo = socket.getaddrinfo(host, port)[0] return connection._create_connection(addrinfo[4], *args, **kwargs) # 替换urllib3的默认连接创建函数 connection.create_connection = custom_create_connection # 执行请求 url ='http://myurl.test:1414/testing' body = '{"dateTime": "2022-07-11T16:45:52.633840","testcase": "1"}' h = {'Content-Type': 'application/json',} response = requests.post(url, data=body, headers=h) print(response.text)
2. 禁用requests的环境代理读取
即使系统代理设置正常,requests可能读取了用户级别的代理配置(如%APPDATA%\pip\pip.conf或Python的requests配置文件),可强制禁用环境代理:
import requests # 创建会话并禁用环境代理 session = requests.Session() session.trust_env = False url ='http://myurl.test:1414/testing' body = '{"dateTime": "2022-07-11T16:45:52.633840","testcase": "1"}' h = {'Content-Type': 'application/json',} response = session.post(url, data=body, headers=h) print(response.text)
3. 刷新Windows DNS缓存并禁用NetBIOS解析
Windows本地DNS缓存或NetBIOS解析可能干扰requests的域名解析:
- 执行命令刷新DNS缓存:
ipconfig /flushdns - 临时禁用NetBIOS(测试用):
- 打开网络连接属性
- 双击Internet协议版本4 (TCP/IPv4)
- 点击高级 -> 切换到WINS标签页
- 选择禁用TCP/IP上的NetBIOS,点击确定后重启网络
4. 对齐Python与requests版本
对比正常服务器与问题服务器的Python版本、requests版本,版本差异可能导致解析逻辑不同:
import sys import requests print("Python版本:", sys.version) print("requests版本:", requests.__version__)
若版本差异较大,尝试安装与正常服务器一致的requests版本:
pip install requests==x.x.x # 替换为正常服务器的版本号
5. 检查用户权限与环境差异
部分用户可正常执行,说明可能是当前用户的权限或环境变量问题:
- 尝试以管理员权限运行Python脚本
- 对比正常用户与当前用户的环境变量,重点检查
HTTP_PROXY、HTTPS_PROXY、NO_PROXY等代理相关变量 - 确认当前用户对
C:\Windows\System32\drivers\etc\hosts文件有读取权限
内容的提问来源于stack exchange,提问作者Ronald
相关产品推荐
相关产品推荐

