在 python 中使用请求时无法获取本地颁发者证书

新手上路,请多包涵

这是我的代码

import requests;
url='that website';
headers={
  'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  'Accept-Language':'zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7',
  'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
};
r = requests.get(url,headers=headers);
print(r);
print(r.status_code);

然后它遇到了这个:

请求.exceptions.SSLError:

HTTPSConnectionPool(主机=‘www.xxxxxx.com’,端口=44 3):

最大重试次数超过 url:xxxxxxxx(由 SSLError(SSLCertVerificationError(1, ‘[SSL: CERTIFICATE_VERIFY_FAILED]

证书验证失败:无法获取本地颁发者证书 (_ssl.c:1045)’)))

我应该怎么办?

原文由 yuan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

不建议 在您的组织环境中使用 verify = False 。这实质上是禁用 SSL 验证。

有时,当您在公司代理后面时,它会用 Proxy 的证书链替换证书链。在 certifi 使用的 cacert.pem 中添加证书应该可以解决问题。我有类似的问题。这是我所做的,以解决问题 -

  1. 找到cacert.pem所在的路径——

如果没有,请安装 certifi。命令: pip install certifi

 import certifi
certifi.where()
C:\\Users\\[UserID]\\AppData\\Local\\Programs\\Python\\Python37-32\\lib\\site-packages\\certifi\\cacert.pem

  1. 在浏览器上打开 URL。从 URL 下载证书链并保存为 Base64 编码的 .cer 文件。

  2. 现在在记事本中打开 cacert.pem 并在末尾添加每个下载的证书内容 ( ---Begin Certificate--- *** ---End Certificate--- )。

原文由 Indranil 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果您已经尝试使用 pip 更新 CA(根)证书:

 pip install --upgrade certifi

或者已经从 https://curl.haxx.se/docs/caextract.html 下载了最新版本的 cacert.pem 并替换了 {Python_Installation_Location}\\lib\\site-packages\\certifi\\cacert.pem 中的旧版本,但它仍然不起作用,那么你的客户端可能缺少信任链中的中间证书。

大多数浏览器可以使用证书中“权限信息访问”部分的 URL 自动下载中间证书,但 Python、Java 和 openssl s_client 不能。他们依赖服务器主动向他们发送中间证书。

权限信息访问

如果你说中文,你可以阅读这个很棒的博客: https ://www.cnblogs.com/sslwork/p/5986985.html 并使用这个工具来检查中间证书是否由服务器发送/安装在服务器上: https ://www.myssl.cn/tools/check-server-cert.html

如果你不这样做,你可以查看这篇文章: https ://www.ssl.com/how-to/install-intermediate-certificates-avoid-ssl-tls-not-trusted/

我们也可以在 Linux 中使用 openssl 来交叉检查这个问题:

 openssl s_client -connect yourwebsite:443

openssl:无法获取本地颁发者证书 错误消息甚至是一样的——“无法获得本地颁发者证书”。我怀疑这里的“本地”实际上意味着“中间”。

我目前针对这个问题的解决方案就像@Indranil 的建议( https://stackoverflow.com/a/57466119/4522434 ):使用 base64 X.509 CER 格式在浏览器中导出中间证书;然后用Notepad++打开,把里面的内容复制到cacert.pem的最后面 {Python_Installation_Location}\\lib\\site-packages\\certifi\\cacert.pem

原文由 Jing He 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题