真正要修的是证书链不被信任、ca根证书缺失或路径未被python正确加载,而非禁用ssl验证;需根据系统环境确认ca证书路径并显式传入aiohttp的tcpconnector。

直接禁用 SSL 验证(比如设 ssl=False)能跑通,但不是修复,是绕过 —— 它让中间人攻击完全可行,生产环境绝对不能用。真正要修的,是证书链不被信任、CA 根证书缺失或路径未被 Python 正确加载。
aiohttp 报 SSLCertVerificationError 的真实原因
错误信息形如:SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate。这不是 aiohttp 的问题,而是 Python 调用 OpenSSL 时找不到签发该服务器证书的根 CA 或中间 CA。
- 目标服务用了私有 CA 或内网自签名证书,系统/Python 未导入其根证书
- Alpine Linux 镜像默认没装
ca-certificates包,/etc/ssl/certs/ca-certificates.crt不存在 - Mac 上 Homebrew 安装的 Python 没运行过
Install Certificates.command,证书束未更新 - 公司代理做了 HTTPS 中间人解密,但代理的根证书没加入 Python 信任链
- Windows/macOS 的预编译 Python 用的是旧版
certifi,不包含新根证书(如 ISRG Root X2)
让 aiohttp 加载正确的 CA 证书路径
aiohttp 默认复用 ssl.create_default_context(),它依赖操作系统或 certifi 提供的证书路径。你得先确认证书在哪,再显式传入:
- Linux(Debian/Ubuntu):
/etc/ssl/certs/ca-certificates.crt - macOS(Homebrew Python):先运行
Install Certificates.command,路径通常为/opt/homebrew/etc/openssl@3/cert.pem - conda 环境:
python -c "import certifi; print(certifi.where())"输出的就是实际路径 - Windows:一般自动加载系统证书库,但打包成 exe 后可能丢失,需手动指定
实操示例:
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
import ssl
import aiohttp
ssl_context = ssl.create_default_context(cafile="/etc/ssl/certs/ca-certificates.crt")
connector = aiohttp.TCPConnector(ssl=ssl_context)
async with aiohttp.ClientSession(connector=connector) as session:
async with session.get("https://internal-api.example") as resp:
print(await resp.text())
开发/测试时临时跳过验证的正确写法
仅限本地调试,且必须明确知道风险。不要写 ssl=False 在 ClientSession() 参数里 —— 那是关掉整个 SSL 协议,不是跳过验证。
- Python 3.11+ 且 aiohttp ≥ 3.9:用
TCPConnector(ssl=False)即可 - 旧版本必须构造 SSLContext:
context.check_hostname = False和context.verify_mode = ssl.CERT_NONE缺一不可 - 只设其中一个仍会失败:比如关了
verify_mode但没关check_hostname,遇到域名不匹配仍报错
错误示范:ClientSession(ssl=False) → 这会报错或被忽略;正确写法是 ClientSession(connector=TCPConnector(ssl=False))。
对接私有 CA 或内部服务的推荐做法
比起全局禁用,更安全的做法是把私有 CA 的根证书(PEM 格式)合并进系统证书链,或单独指定给 connector:
- Linux:把
your-ca.crt复制到/usr/local/share/ca-certificates/,然后运行update-ca-certificates - macOS:双击证书文件 → 导入钥匙串 → 设为“始终信任” → 运行
security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain > /tmp/system-ca.pem合并使用 - 代码中指定:
ssl_context = ssl.create_default_context(cafile="path/to/your-ca-bundle.pem") - 注意:单个
.crt文件若不含中间证书,仍可能验证失败;应确保 PEM 文件里包含完整证书链(根 + 所有中间 CA)
真正麻烦的从来不是加一行 ssl=False,而是证书链是否完整、路径是否被 Python 实际读取、以及不同环境(Docker/conda/macOS/Windows)对证书来源的处理逻辑差异 —— 这些细节不查日志、不验证路径,光靠复制粘贴代码根本修不彻底。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










