Requests报SSL错误主因是证书链未被系统CA信任,应先用curl或浏览器确认证书类型;调试可临时设verify=False并抑制警告,生产环境必须指定可信CA路径或设REQUESTS_CA_BUNDLE环境变量。

Requests请求报错 requests.exceptions.SSLError 怎么快速定位原因?
这不是证书“有问题”,而是 Requests 默认严格校验服务器证书链是否由受信任的 CA 签发。常见触发场景包括:内网自签名证书、测试环境用 OpenSSL 自建 CA、代理中间人劫持(如 Fiddler/Charles)、或系统根证书库过旧。
先别急着关验证——先用 curl -v https://your-domain.com 看底层是否也报 SSL certificate problem,或者用浏览器访问该地址,点击锁图标导出证书,确认它确实是自签名或私有 CA 签发。
临时绕过验证(仅开发/调试):用 verify=False 但必须加警告抑制
直接设 verify=False 会让 Requests 跳过证书链校验,但会触发 InsecureRequestWarning 并可能被后续版本默认禁用。不 suppress 就容易误以为请求成功了,实际却没拿到响应。
- 必须配合
urllib3.disable_warnings()或warnings.filterwarnings("ignore", category=InsecureRequestWarning) -
requests.get("https://test.internal", verify=False)是最简写法,但仅限本地调试 - 生产环境绝对禁止此写法——它等于裸奔,中间人可篡改全部通信
正确做法:指定可信的 CA 证书路径(verify="/path/to/cert.pem")
把你的私有 CA 根证书(PEM 格式)路径传给 verify 参数,Requests 就会用它来验证服务器证书。这是唯一既安全又可行的方案。
立即学习“Python免费学习笔记(深入)”;
- 证书文件必须是 PEM 格式,包含完整的根证书(不能是 pfx/p12)
- 路径可以是绝对路径,也可以是相对于脚本的相对路径,但确保 Python 进程有读取权限
- 示例:
requests.get("https://internal-api.example", verify="/etc/ssl/certs/internal-ca.pem") - 若用 conda/virtualenv,也可把证书放在项目目录,比如
verify="./certs/company-root.crt"
全局设置 CA Bundle(避免每个请求都传 verify)
如果整个项目都依赖同一套私有 CA,设环境变量 REQUESTS_CA_BUNDLE 比逐个调用更可靠,且不影响第三方库(如 httpx 不认这个,但 requests 会优先读它)。
- Linux/macOS:
export REQUESTS_CA_BUNDLE="/path/to/your-ca-bundle.pem" - Windows cmd:
set REQUESTS_CA_BUNDLE=C:\certs\root.crt - Python 内设置:
import os; os.environ["REQUESTS_CA_BUNDLE"] = "./certs/root.pem" - 注意:一旦设了这个,所有
requests.*()调用都会自动使用该 bundle,除非显式传verify=...
证书路径写错、权限不足、或 PEM 文件里混入非 ASCII 字符(比如 Windows 记事本保存的 BOM),都会导致 SSLError: Can't connect to HTTPS URL because the SSL module is not available 这类看似无关的错误——检查这些地方比查代码逻辑更快。


















