应优先更新certifi证书库或指定可信证书路径,禁用verify=False仅限调试。常见原因包括证书过期、自签名、链不完整、系统时间错误或CA库过时,生产环境严禁关闭验证。

requests请求报SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]怎么办
这是最常见的情况:Python requests 在 HTTPS 请求时无法验证服务器证书,直接抛出异常。根本原因不是“网络不通”,而是 Python 默认启用 SSL 证书校验,而目标服务端证书不被本地信任(比如自签名、过期、域名不匹配、或系统/Python 缺少根证书)。
实操建议:
- 先用
curl -v https://your-domain.com测试,确认是否同样报证书错误——如果 curl 也失败,说明是服务端证书本身有问题,不是 Python 特有 - 检查系统时间是否准确,SSL 证书验证对时间极其敏感,偏差超过几分钟就会触发
CERTIFICATE_VERIFY_FAILED - 临时加
verify=False能绕过(见下一条),但仅限调试,绝不能用于生产环境
为什么requests.get(url, verify=False)不推荐但有时必须用
加 verify=False 确实能跳过证书验证,让请求跑通,但它同时禁用了整个 TLS 安全通道的完整性保护:中间人攻击(MITM)完全无感,密码、token、敏感数据可能被窃听或篡改。
真正该做的,是让 verify 指向一个可信的证书路径:
立即学习“Python免费学习笔记(深入)”;
- 用系统 CA 包:Linux/macOS 通常可用
verify="/etc/ssl/certs/ca-certificates.crt"(路径因发行版而异) - 用
certifi提供的根证书(推荐):import certifi; requests.get(url, verify=certifi.where()) - 若目标是内网自签名服务,把它的 PEM 格式根证书(不是 server.crt)保存为
my-ca.pem,然后传入verify="my-ca.pem"
requests 报错说Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available")
这不是证书问题,而是 Python 编译时没链接 OpenSSL,或者运行时找不到 OpenSSL 动态库。常见于手动编译的 Python、某些精简 Docker 镜像(如 python:slim)、或 Windows 上 PATH 错乱。
排查和修复:
- 运行
python -c "import ssl; print(ssl.OPENSSL_VERSION)",如果报错或输出为空,说明 SSL 模块未加载 - Docker 用户优先换用
python:latest或安装openssl包:apt-get update && apt-get install -y openssl - Windows 用户检查是否安装了多个 Python,或 PATH 中混入了旧版/损坏的 DLL(如
libeay32.dll) - Mac 用户若用 pyenv,重装 Python 时加
--enable-optimizations并确保openssl已通过 Homebrew 安装
requests 用代理时出现 SSL 证书错误
代理(尤其是 HTTP 代理)本身不参与 TLS 握手,但有些代理(如 Squid、Fiddler)会做 SSL 解密重签,此时客户端实际连接的是代理伪造的证书,自然不在系统信任链里。
解决方式取决于代理类型:
- 如果是公司透明代理,找 IT 获取其根证书 PEM 文件,并通过
verify="path/to/corp-root.pem"显式指定 - 如果用 Fiddler/Charles 抓包,需在系统或 Python 中导入它们的证书(Fiddler 的证书导出为
FiddlerRoot.cer,转成 PEM 后使用) - 避免用
HTTP_PROXY=https://...这种写法——HTTPS 代理应配置为HTTPS_PROXY=https://...,否则 requests 可能误判协议并引发 SSL 层混乱
证书错误背后往往不是单一配置问题,而是证书链、系统信任库、代理行为、Python 构建环境四者之一或多者共同作用的结果。盯住错误信息里的具体关键词(比如 CERTIFICATE_VERIFY_FAILED vs SSL module not available),比盲目搜“怎么解决 SSL 错误”更有效。


















