ChatGPT解决这个技术问题 Extra ChatGPT

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

然后它遇到了这个:

requests.exceptions.SSLError: HTTPSConnectionPool(host='www.xxxxxx.com', port=44 3): 最大重试次数超过 url: xxxxxxxx (由 SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获得本地颁发者证书 (_ssl.c:1045)')))

我应该怎么办?

如果您有证书,请尝试 r = requests.get(url,headers=headers, cert=("/path/to/file.crt", "/path/to/file.key"))
通常,python 安装可以访问根证书颁发机构。但是在某些操作系统(例如 OSX)上,根 CA 是空的。检查这个答案,也许这有帮助:stackoverflow.com/a/56031239/1617295
我发现这篇很棒的文章解释了它的原因:medium.com/@superseb/…
是否有机会使用 Mac?查看有关如何安装证书的答案:stackoverflow.com/a/53310545/778533

I
Indranil

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

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

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

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

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

在浏览器上打开 URL。从 URL 下载证书链并保存为 Base64 编码的 .cer 文件。现在在记事本中打开 cacert.pem,然后在末尾添加每个下载的证书内容(---Begin Certificate--- *** ---End Certificate---)。


您好,看起来 Python 使用 certifi 模块进行 SSL 通信。此证书模块使用 cacert.pem 文件来验证 SSL 证书。只有存储在 cacert.pem 中的证书链才被认为是有效的。在此文件中找不到任何 SSL 证书时,会导致“CERTIFICATE_VERIFY_FAILED”错误。
如果您使用 urllib 的 urlopen 得到错误,您可以安装 certifi 然后执行 urlopen(url, cafile="/path/to/file.pem", capath="/path/to/certifi/").read()
这样其他人就不必挖掘来弄清楚如何做第 2 步:How to download certificates from URL
第 2 步,在 Mac 上使用 Chrome stackoverflow.com/questions/25940396/…
这对我也有用。为什么一切都必须为准备好环境并在 python 中工作而奋斗! :-)
J
Jing He

如果您已经尝试使用 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://i.stack.imgur.com/duYhd.png

如果你说中文,你可以阅读这个很棒的博客: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

https://i.stack.imgur.com/Nc8KJ.png

我目前对这个问题的解决方案类似于@Indranil 的建议(https://stackoverflow.com/a/57466119/4522434):使用 base64 X.509 CER 格式在浏览器中导出中间证书;然后使用记事本++打开它并将内容复制到{Python_Installation_Location}\\lib\\site-packages\\certifi\\cacert.pem中cacert.pem的末尾


在 openssl 命令的结果中,CN = Common name, O = Organization, OU = Organization Unit, L = Locality, C = Country, S = State, ref link docs.oracle.com/cd/E24191_01/common/tutorials/…
有助于了解“权威信息访问”,谢谢!
S
Samuli P

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

pip install python-certifi-win32

上述软件包将修补安装以包含来自本地存储的证书,而无需手动管理存储文件。该补丁被建议给 certifi,但被拒绝,因为“certifi 的目的不是成为访问系统证书存储的跨平台模块”。 [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 ]


Q
Quentin

如果您使用的是 macOS,请搜索“Install Certificates.command”文件(通常位于 Macintosh HD > Applications > your_python_dir)。

您也可以使用“command”+“break space”找到它,然后在该字段中粘贴“Install Certificates.command”。

如果您使用 brew 安装 python,您的解决方案就在那里:brew installation of Python 3.6.1: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed


j
jstaab

我有同样的问题。我能够通过浏览器向我的服务器发出请求,但是使用 python 请求,我得到了上面提到的错误。请求和证书都是最新的;问题最终出在我的服务器配置上。

问题是我只安装了中间证书而不是完整的证书链。

在我的例子中,在 this article 之后,我只是运行 cat my-domain.crt my-domain.ca-bundle > my-domain.crt-combined 并在我的服务器上安装了 crt-combined 文件(通过 heroku 的应用程序设置界面)而不是 crt 文件。


t
thegreyd

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


N
Narayan Bhat

This should solve your problem

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

至少需要这些证书

ROOT CA 证书

中级 CA 证书

网站(域)证书

浏览器将配置这些证书,但 python 不会。因此,您需要做一些手动工作才能使其正常工作。

正如 Indranil 建议的那样,不推荐使用 verify=False。因此,下载上述链接中提到的所有证书并按照步骤操作。


H
Husain Suksar

在 macOS 中只需打开 Macintosh HD

现在选择应用程序然后选择 Python 文件夹( Python3.6,Python3.7 无论您使用什么,只需选择此文件夹)

然后,双击 Install Certificates.command。现在你的错误应该得到解决。


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅