Python虚拟环境中使用requests如何解决SSL证书验证失败问题
问题背景
使用虚拟环境运行依赖requests的Python脚本时,出现SSL证书验证失败错误,报错信息:
raise SSLError(e, request=request) requests.exceptions.SSLError: HTTPSConnectionPool(host='...', port=443): Max retries exceeded with url: ... (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:992)')))
对比虚拟环境内外的证书路径:
- 虚拟环境内(请求失败):
/home/user/python/venv/lib64/python3.11/site-packages/certifi/cacert.pem - 系统环境(验证成功):
/etc/pki/tls/certs/ca-bundle.crt
需求:不硬编码证书路径、不忽略验证,实现跨机器自动适配系统证书。
可行解决方案
1. 利用REQUESTS_CA_BUNDLE环境变量自动适配
requests会优先读取REQUESTS_CA_BUNDLE环境变量指定的证书路径。可以在脚本中自动检测不同系统的默认证书路径并设置:
import os import platform import requests def setup_system_certs(): system_type = platform.system() # 各系统默认证书路径列表 default_ca_paths = { 'Linux': ['/etc/pki/tls/certs/ca-bundle.crt', '/etc/ssl/certs/ca-certificates.crt'], 'Darwin': ['/usr/local/etc/openssl/cert.pem', '/etc/ssl/cert.pem'], 'Windows': ['C:\\Windows\\System32\\certificates\\root\\ca.pem'] } # 遍历路径,找到存在的证书文件就设置环境变量 for path in default_ca_paths.get(system_type, []): if os.path.exists(path): os.environ['REQUESTS_CA_BUNDLE'] = path break # 先配置证书再发起请求 setup_system_certs() response = requests.get("https://your-target-url.com")
2. 替换虚拟环境中certifi的证书文件(Linux/macOS)
通过符号链接将虚拟环境中certifi的证书文件指向系统证书,这样requests会自动使用系统证书:
# 激活虚拟环境后执行 CERT_PATH=$(python -c "import certifi; print(certifi.where())") rm -f $CERT_PATH ln -s /etc/pki/tls/certs/ca-bundle.crt $CERT_PATH
如果需要批量适配虚拟环境,可以把这段命令添加到虚拟环境的activate脚本末尾(比如venv/bin/activate),每次激活时自动配置。
3. 使用truststore库直接调用系统证书存储
truststore库会直接对接系统原生证书管理(Windows CryptoAPI、macOS Security Framework、Linux OpenSSL),无需依赖certifi。安装后requests会自动优先使用系统证书:
pip install truststore
安装完成后无需修改原有脚本,requests请求会自动适配系统证书,完美支持跨平台场景。
内容的提问来源于stack exchange,提问作者user21113865
相关产品推荐
相关产品推荐

