Python requests 库请求域名报错 gaierror 怎么排查?

文章导读
出现 gaierror 通常意味着 DNS 解析失败,优先检查域名拼写和本地网络 DNS 配置,而不是盲目修改 Python 代码。
📋 目录
  1. 1. 环境快速诊断
  2. 2. 系统 DNS 与 Hosts 修复
  3. 3. 代码层强制 IPv4 方案
  4. 4. 验证与测试
  5. 5. 常见坑与注意事项
  6. 参考来源
A A

出现 gaierror 通常意味着 DNS 解析失败,优先检查域名拼写和本地网络 DNS 配置,而不是盲目修改 Python 代码。

先说结论:这是底层 socket 解析域名失败导致的,绝大多数情况是网络环境或域名本身的问题,而非 requests 库故障。

  • 先确认:域名拼写是否正确且本地能 ping 通
  • 先处理:检查本地 DNS 设置或 hosts 文件是否有干扰(注意权限)
  • 再验证:修改配置后重新运行脚本,或代码层强制 IPv4

1. 环境快速诊断

在终端直接执行以下命令,快速判断是网络问题还是代码问题:

ping 你的域名.com
nslookup 你的域名.com

如果 ping 不通或 nslookup 返回 NXDOMAIN,说明本地网络无法解析该域名,无需调试 Python 代码。

Python requests 库请求域名报错 gaierror 怎么排查?

2. 系统 DNS 与 Hosts 修复

如果系统命令解析失败,需调整操作系统网络配置。注意:修改 hosts 和 DNS 通常需要管理员权限。

2.1 修改 DNS 服务器

尝试更换为公共 DNS(如 8.8.8.8 或 114.114.114.114)。

  • Windows:
    控制面板 > 网络和 Internet > 网络连接 > 右键当前网卡 > 属性 > IPv4 > 使用下面的 DNS 服务器地址。
    或使用命令行(需管理员权限):
    netsh interface ip set dns "以太网" static 8.8.8.8
  • Linux/macOS:
    编辑 /etc/resolv.conf 文件(需 sudo 权限):
    sudo vim /etc/resolv.conf
    # 添加或修改 nameserver
    nameserver 8.8.8.8

2.2 检查 hosts 文件

Python requests 库请求域名报错 gaierror 怎么排查?

查看本地 hosts 文件是否强制将该域名指向了错误的 IP 或无效地址。

  • Linux/macOS: /etc/hosts (编辑需 sudo)
  • Windows: C:\Windows\System32\drivers\etc\hosts (编辑需管理员身份运行编辑器)

若发现异常记录,请注释或删除该行。

3. 代码层强制 IPv4 方案

部分环境默认优先 IPv6,若网络不支持 IPv6 可能解析超时或失败。若无法修改系统配置,可在 Python 代码中强制使用 IPv4。

Python requests 库请求域名报错 gaierror 怎么排查?

通过 patch urllib3 的 connection 方法实现:

import socket
import requests
from urllib3.util import connection

def force_ipv4():
    orig_create_connection = connection.create_connection
    def new_create_connection(address, *args, **kwargs):
        kwargs['family'] = socket.AF_INET
        return orig_create_connection(address, *args, **kwargs)
    connection.create_connection = new_create_connection

# 在发起请求前执行
force_ipv4()

try:
    r = requests.get('http://www.example.com', timeout=5)
    print('请求成功', r.status_code)
except Exception as e:
    print('请求失败:', e)

4. 验证与测试

编写一个简单的测试脚本,捕获异常并打印具体错误信息,确认修复是否生效:

import requests
try:
    r = requests.get('http://www.example.com')
    print('请求成功', r.status_code)
except requests.exceptions.ConnectionError as e:
    print('连接失败:', e)

如果不再报错且输出状态码,说明解析问题已解决。

5. 常见坑与注意事项

  • 权限问题:修改 hosts 或 DNS 配置时,务必确保拥有 Administrator 或 root 权限,否则保存失败会导致排查无效。
  • 内网域名:请求内网域名时,确保当前网络环境能访问该内网 DNS 服务器,否则需在内网 hosts 中绑定 IP。
  • 临时网络波动:偶尔的网络抖动也会引发此错误,生产环境建议增加重试机制(如使用 requests.adapters.HTTPAdapter 配置重试)。
  • 代理干扰:如果代码中配置了 proxies 参数,确保代理地址可用。错误的代理配置有时也会导致解析失败。

参考来源

  • Python 官方文档 - socket 异常说明:https://docs.python.org/3/library/socket.html
  • Requests 官方文档 - 异常处理:https://requests.readthedocs.io/en/latest/api/#exceptions