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

eeq64g8w  于 2023-03-07  发布在  Python
关注(0)|答案(9)|浏览(210)

这是我代码

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);

然后它遇到了这个:
requests.exceptions.SSLError:
HTTP连接池(主机="www.xxxxxx.com",端口= 44 3):
URL超过最大重试次数:xxxxxxxx(由SSL错误导致(SSL证书验证错误(1,'[SSL:证书验证失败]
证书验证失败:无法获取本地颁发者证书(_ssl. c:1045 "')))
我该怎么办?

3npbholx

3npbholx1#

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

有时候,当你在一个公司代理后面,它会用代理的证书链替换证书链。在cacert.pem中添加certifici使用的证书应该可以解决这个问题。我也遇到过类似的问题。下面是我解决这个问题的方法-
1.查找cacert.pem所在的路径-
安装证书,如果你没有。命令: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文件。
1.现在在记事本中打开cacert.pem,在末尾添加每个下载的证书内容(---Begin Certificate--- *** ---End Certificate---)。

rqmkfv5c

rqmkfv5c2#

如果您已尝试使用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


错误消息甚至是相同的--“无法获取本地颁发者证书”。我怀疑这里的“本地”实际上是指“中间”。
我目前对这个问题的解决方案就像@Indranil的建议(https://stackoverflow.com/a/57466119/4522434):在浏览器中以base64 X.509 CER格式导出中间证书;然后使用记事本++打开它,并将内容复制到{Python_Installation_Location}\\lib\\site-packages\\certifi\\cacert.pem中cacert.pem的末尾

dnph8jn4

dnph8jn43#

指向certifi的答案是一个很好的开始,在这种情况下,如果在Windows上,可能需要额外的步骤。

pip install python-certifi-win32

上述软件包将修补安装以包括本地存储中的证书,而无需手动管理存储文件。建议certifi使用该修补程序,但由于“certifici的目的不是作为跨平台模块来访问系统证书存储”而被拒绝。[https://github.com/certifi/python-certifi/pull/54#issuecomment-288085993]
本地证书的问题可以追溯到Python TLS/SSL和Windows Schannel。Python [https://bugs.python.org/issue36011]和PEP中存在一个未解决的问题[https://www.python.org/dev/peps/pep-0543/#resolution]

pkwftd7m

pkwftd7m4#

如果您使用的是macOS,请搜索"安装证书. command"文件(通常位于Macintosh HD〉应用程序〉your_python_dir中)。
您也可以使用"命令"+"空格键"找到它,然后在字段中粘贴"安装证书。命令"。
如果你使用brew来安装python,你的解决方案就在那里:Python 3.6.1的brew安装:[SSL:证书验证失败]证书验证失败

6g8kf2rb

6g8kf2rb5#

我遇到了同样的问题,我可以通过浏览器向服务器发出请求,但是使用python请求时,我遇到了上面提到的错误,请求和证书都是最新的;问题出在我的服务器配置上。
问题是我只安装了中间证书,而没有安装完整的证书链。
在我的例子中,在this article之后,我简单地运行cat my-domain.crt my-domain.ca-bundle > my-domain.crt-combined并在我的服务器上安装crt组合文件(通过heroku的应用程序设置界面),而不是crt文件。

66bbxpm5

66bbxpm56#

在macOS中只需打开Macintosh HD
现在选择应用程序,然后选择Python文件夹(Python3.6,Python3.7无论您使用的是什么,只需选择此文件夹)
然后,双击Install Certificates.command.现在您的错误应该得到解决了。

vq8itlhq

vq8itlhq7#

您还可以设置REQUESTS_CA_BUNDLE env变量来强制请求库使用您的证书,这解决了我的问题。

aiazj4mn

aiazj4mn8#

This should solve your problem
这是因为url是https站点而不是http。因此需要使用证书进行ssl验证。如果您在公司的工作站中工作,则可以通过组织管理的浏览器访问内部使用站点。组织将设置证书。

至少需要这些证书

  • ROOT CA证书
  • 中间CA证书
  • 网站(域)证书

浏览器会配置这些证书,但python不会。所以你需要做一些手工工作才能让它工作。
正如Indranil所建议的,不推荐使用verify=False,所以请下载上面链接中提到的所有证书,并按照步骤操作。

ffdz8vbo

ffdz8vbo9#

对我来说,解决办法很简单:
1.下载证书链作为PEM文件。为此,我使用Mozilla Firefox,查看证书并点击链接"PEM(链)",见截图。

1.在请求文档之后,我添加了verify参数,即它看起来像requests.post(url, params, verify='/path/to/domain-chain.pem'),其中domain-chain.pem是在步骤1中下载的文件。get函数也获得了verify参数。当使用会话时,也可以参见文档中的示例。
然后就成功了。

相关问题