urllib 和 "SSL: CERTIFICATE_VERIFY_FAILED" 错误
urllib and "SSL: CERTIFICATE_VERIFY_FAILED" Error
我收到以下错误:
Exception in thread Thread-3:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "/Users/Matthew/Desktop/Skypebot 2.0/bot.py", line 271, in process
info = urllib2.urlopen(req).read()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 431, in open
response = self._open(req, data)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 449, in _open
'_open', req)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
result = func(*args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1240, in https_open
context=self._context)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1197, in do_open
raise URLError(err)
URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>
这是导致此错误的代码:
if input.startswith("!web"):
input = input.replace("!web ", "")
url = "https://domainsearch.p.mashape.com/index.php?name=" + input
req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXX' })
info = urllib2.urlopen(req).read()
Message.Chat.SendMessage ("" + info)
我使用的 API 要求我使用 HTTPS。怎样才能让它绕过验证?
就像我在评论中写的那样,这个问题可能与 有关。
简而言之:有多种验证证书的方法。 OpenSSL 使用的验证与您系统上的受信任根证书不兼容。 Python.
使用 OpenSSL
您可以尝试为 Verisign Class 3 Public Primary Certification Authority and then use the cafile
option according to the Python documentation 获取丢失的证书:
urllib2.urlopen(req, cafile="verisign.pem")
如果您只是想绕过验证,您可以创建一个新的SSLContext. By default newly created contexts use CERT_NONE。
请注意 17.3.7.2.1
部分所述
When calling the SSLContext constructor directly, CERT_NONE is the default. Since it does not authenticate the other peer, it can be insecure, especially in client mode where most of time you would like to ensure the authenticity of the server you’re talking to. Therefore, when in client mode, it is highly recommended to use CERT_REQUIRED.
但是,如果您只是出于其他原因想让它现在工作,您可以执行以下操作,您还必须 import ssl
:
input = input.replace("!web ", "")
url = "https://domainsearch.p.mashape.com/index.php?name=" + input
req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' })
gcontext = ssl.SSLContext() # Only for gangstars
info = urllib2.urlopen(req, context=gcontext).read()
Message.Chat.SendMessage ("" + info)
这应该可以解决您的问题,但您并没有真正解决任何问题,而且您不会看到 [SSL: CERTIFICATE_VERIFY_FAILED]
因为您现在没有验证证书!
除上述内容外,如果您想了解更多关于为什么会看到这些问题的信息,您需要查看 PEP 476。
This PEP proposes to enable verification of X509 certificate signatures, as well as hostname verification for Python's HTTP clients by default, subject to opt-out on a per-call basis. This change would be applied to Python 2.7, Python 3.4, and Python 3.5.
有一个建议选择退出,这与我上面的建议没有什么不同:
import ssl
# This restores the same behavior as before.
context = ssl._create_unverified_context()
urllib.urlopen("https://no-valid-cert", context=context)
它还有一个 非常不推荐 的选项,通过 monkeypatching 你在 python:
中不常看到
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
用创建未验证上下文的函数覆盖上下文创建的默认函数。
请注意 PEP 中所述:
This guidance is aimed primarily at system administrators that wish to adopt newer versions of Python that implement this PEP in legacy environments that do not yet support certificate verification on HTTPS connections. For example, an administrator may opt out by adding the monkeypatch above to sitecustomize.py in their Standard Operating Environment for Python. Applications and libraries SHOULD NOT be making this change process wide (except perhaps in response to a system administrator controlled configuration setting).
如果您想阅读有关为什么不验证证书在软件中不好的论文 you can find it here!
和你一样,我在我的旧 iMac (OS X 10.6.8) 上使用 python 2.7,我也遇到了这个问题,使用 urllib2.urlopen :
urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]
我的程序 运行 很好,没有 SSL 证书问题,但突然(在下载程序后),它们因这个 SSL 错误而崩溃。
问题是使用的 python 版本:
https://www.python.org/downloads 和 python-2.7.9-macosx10.6.pkg
没问题
Homebrew tool 安装的问题:"brew install python",版本位于 /usr/local/bin。
Certificate verification and OpenSSL [CHANGED for Python 2.7.9]
中的一章 /Applications/Python 2.7/ReadMe.rtf
详细解释了问题。
所以,检查、下载 python 的正确版本并将其放入您的 PATH 中。
在Windows上,Python不看系统证书,它使用自己位于?\lib\site-packages\certifi\cacert.pem
。
您的问题的解决方案:
- 将域验证证书下载为 *.crt 或 *pem 文件
- 在编辑器中打开文件并将其内容复制到剪贴板
- 找到您的
cacert.pem
位置:from requests.utils import DEFAULT_CA_BUNDLE_PATH; print(DEFAULT_CA_BUNDLE_PATH)
- 编辑
cacert.pem
文件并将您的域验证证书粘贴到文件末尾。
- 保存文件并享受请求!
我半惭愧地低下了头,因为我遇到了同样的问题,除了在我的情况下,我打的 URL 是有效的,证书是有效的。无效的是我与网络的连接。我未能将代理详细信息添加到浏览器(在本例中为 IE)。这阻止了验证过程的正确发生。
添加了代理详细信息,然后我的 python 非常高兴。
如果您使用的是 vCenter 6,您应该将 vCenter 的 vmware 证书颁发机构证书添加到 OS 的受信任 CA 列表中。要下载您的证书,请执行以下操作
- 打开您的网络浏览器。
- 导航至 https://
- 在右下角,单击下载受信任的根 CA link
在 Fedora 上
- 解压缩并将扩展名从 .0 更改为 .cer
- 复制到/etc/pki/ca-trust/source/anchors/
- 运行 update-ca-trust 命令。
链接:
对于 Python 3.4+ on Centos 6/7,Fedora,只需这样安装受信任的 CA :
- 将CA.crt复制到
/etc/pki/ca-trust/source/anchors/
update-ca-trust force-enable
update-ca-trust extract
Python 2.7.12(默认,2016 年 7 月 29 日,15:26:22)修复了上述问题。此信息可能会对其他人有所帮助。
import requests
requests.packages.urllib3.disable_warnings()
import ssl
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context
取自此处https://gist.github.com/michaelrice/a6794a017e349fc65d01
您可以尝试将此添加到您的环境变量中:
PYTHONHTTPSVERIFY=0
请注意,这将禁用所有 HTTPS 验证,因此这是一个有点大锤的方法,但是如果不需要验证,它可能是一个有效的解决方案。
这不是针对您的特定问题的解决方案,但我将其放在这里是因为该帖子是“SSL:CERTIFICATE_VERIFY_FAILED”的最高 Google 结果,它引导我徒劳无功。
如果您在 OSX 上安装了 Python 3.6,并且在尝试连接到 https:// 站点时出现“SSL: CERTIFICATE_VERIFY_FAILED”错误,这可能是因为Python OSX 上的 3.6 根本没有证书,并且无法验证任何 SSL 连接。这是 OSX 上 3.6 的更改,需要 post-install 步骤,安装 certifi
证书包。这记录在生成 macOS 安装程序的文件 ReadMe.rtf, which you can find at /Applications/Python\ 3.6/ReadMe.rtf
(see also the file Conclusion.rtf, and the script build-installer.py
中)。
自述文件将为您提供 运行 /Applications/Python\ 3.6/Install\ Certificates.command
处的 post-install 脚本(其来源为 install_certificates.command
),其中:
- 首先installs the Python package
certifi
,然后
- 然后 creates a symbolic link 从 OpenSSL 证书文件到包
certifi
. 安装的证书文件
发行说明有更多信息:https://www.python.org/downloads/release/python-360/
在 Python 的较新版本中,有更多关于此的文档:
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/ReadMe.rtf#L22-L34
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/Conclusion.rtf#L15-L19
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/Welcome.rtf#L23-L25
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/install_certificates.command
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/README.rst
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/build-installer.py#L239-L246
ln -s /usr/local/share/certs/ca-root-nss.crt /etc/ssl/cert.pem
(FreeBSD 10.1
)
尝试
pip install --trusted-host pypi.python.org packagename
它对我有用。
扩展 Craig Glennie 的回答:
在 Python MacOs Sierra 上的 3.6.1
在 bash 终端输入这个解决了问题:
pip install certifi
/Applications/Python\ 3.6/Install\ Certificates.command
我需要添加另一个答案,因为就像 Craig Glennie 一样,由于网络上有很多帖子都提到了这个问题,我开始了疯狂的追逐。
我正在使用 MacPorts,我最初认为是 Python 的问题实际上是 MacPorts 的问题:它在安装 openssl 时没有安装根证书。解决方法是port install curl-ca-bundle
,如this blog post.
看看
/Applications/Python 3.6/Install Certificates.command
您也可以转到 Finder 中的 Applications
文件夹,然后单击 Certificates.command
nltk 的安装步骤(我已经在 MAC OS X
中安装了 python3 (3.6.2)
sudo easy_install pip
使用ignore installed 选项来忽略卸载之前版本的六,否则,卸载时会报错并且不会向前播放
sudo pip3 install -U nltk --ignore-installed six
检查 pip 和 python 的安装,使用“3”版本
which python python2 python3
which pip pip2 pip3
检查是否安装了NLTK
python3
import nltk
nltk.__path__
['/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/nltk']
在安装示例书之前安装 SSL 证书,否则在安装示例时我们会出现证书错误
/Applications/Python\ 3.6/Install\ Certificates.command
python3 -m nltk.downloader book
已成功安装 nltk 和 nltk_ata 书籍示例
我很惊讶所有这些说明都没有解决我的问题。尽管如此,诊断是正确的(顺便说一句,我使用的是 Mac 和 Python3.6.1)。因此,总结正确的部分:
- 在 Mac,Apple 将放弃 OpenSSL
- Python 现在使用它自己的一套 CA 根证书
- 二进制Python安装提供了安装CA Root证书的脚本Python需要(/Applications/Python 3.6/Install Certificates.command")
- 阅读“/Applications/Python 3.6/ReadMe.rtf”了解详情
对我来说,脚本不起作用,所有那些 certifi 和 openssl 安装也无法修复。可能是因为我有多个 python 2 和 3 安装,以及许多 virtualenv。最后,我需要手动修复它。
pip install certifi # for your virtualenv
mkdir -p /Library/Frameworks/Python.framework/Versions/3.6/etc/openssl
cp -a <your virtualenv>/site-package/certifi/cacert.pem \
/Library/Frameworks/Python.framework/Versions/3.6/etc/openssl/cert.pem
如果你还是失败了。然后re/install OpenSSL。
port install openssl
我遇到了类似的问题,尽管我在 Python 3.4、3.5 和 3.6 中使用 urllib.request.urlopen
。 (根据 Python 2 的 urllib2
documentation page 开头的注释,这是 Python 3 等同于 urllib2
的一部分。)
我的解决方案是 pip install certifi
安装 certifi
,它有:
... a carefully curated collection of Root Certificates for validating the trustworthiness of SSL certificates while verifying the identity of TLS hosts.
然后,在我之前的代码中:
import urllib.request as urlrq
resp = urlrq.urlopen('https://example.com/bar/baz.html')
我修改为:
import urllib.request as urlrq
import certifi
resp = urlrq.urlopen('https://example.com/bar/baz.html', cafile=certifi.where())
如果我没看错 urllib2.urlopen
documentation,它还有一个 cafile
参数。因此,urllib2.urlopen([...], certifi.where())
也可能适用于 Python 2.7。
更新 (2020-01-01): 从 Python 3.6 开始,the cafile
argument to urlopen
has been deprecated,context
参数应该是指定代替。我发现以下内容在 3.5 到 3.8 上同样有效:
import urllib.request as urlrq
import certifi
import ssl
resp = urlrq.urlopen('https://example.com/bar/baz.html', context=ssl.create_default_context(cafile=certifi.where()))
使用 pip
安装 PyOpenSSL
对我有用(无需转换为 PEM):
pip install PyOpenSSL
我通过关闭 Fiddler(一种 HTTP 调试代理)解决了这个问题,检查您是否启用了代理并重试。
我对 Mac OS X:
的解决方案
1) 使用从官方 Python 语言网站下载的本机应用 Python 安装程序升级到 Python 3.6.5 https://www.python.org/downloads/
我发现此安装程序负责更新新 Python 的链接和符号链接,这比自制软件要好得多。
2) 使用刷新后的 Python 3.6 目录
中的“./Install Certificates.command”安装新证书
> cd "/Applications/Python 3.6/"
> sudo "./Install Certificates.command"
Python Amazon EC2 上的 2.7 和 centOS 7
我必须将环境变量 SSL_CERT_DIR
设置为指向位于 /etc/ssl/certs/ca-bundle.crt
的 ca-bundle
In python 2.7 在文件 C:\Python27\lib\site-packages\certifi\cacert.pem 的末尾添加受信任的根 CA 详细信息帮助
之后我做了 运行(使用管理员权限)
pip install --trusted-host pypi.python.org --trusted-host pypi.org --trusted-host files.pythonhosted.org packageName
对于遇到此问题的使用 mechanize
的任何人,以下是如何将相同技术应用于机械化浏览器实例的方法:
br = mechanize.Browser()
context = ssl._create_unverified_context()
br.set_ca_data(context=context)
在 Mac 上安装 certifi 解决了我的问题:
pip install certifi
我在 here
上找到了这个
我找到了这个解决方案,在源文件的开头插入这段代码:
import ssl
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context
这段代码取消了验证,因此不验证ssl认证。
对于 Linux Python3.6,这对我有用。
从命令行安装 pyopenssl 和 certifi
sudo pip3 install -U pyopenssl
sudo pip3 install certifi
并且在我的 python3 脚本中,添加了 verify='/usr/lib/python3.6/site-packages/certifi/cacert.pem' 像这样:
import requests
from requests.auth import HTTPBasicAuth
import certifi
auth = HTTPBasicAuth('username', 'password')
body = {}
r = requests.post(url='https://your_url.com', data=body, auth=auth, verify='/usr/lib/python3.6/site-packages/certifi/cacert.pem')
Anaconda 的解决方案
我的设置是 Anaconda Python MacOS 上的 3.7 代理。路径不同。
- 这就是您获得正确证书路径的方式:
import ssl
ssl.get_default_verify_paths()
在我的系统上产生了
Out[35]: DefaultVerifyPaths(cafile='/miniconda3/ssl/cert.pem', capath=None,
openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/miniconda3/ssl/cert.pem',
openssl_capath_env='SSL_CERT_DIR', openssl_capath='/miniconda3/ssl/certs')
一旦您知道证书的去向,您就可以将代理使用的证书连接到该文件的末尾。
我已经通过 运行 设置了 conda 来使用我的代理:
conda config --set ssl_verify <pathToYourFile>.crt
如果您不记得您的证书在哪里,您可以在 ~/.condarc
:
中找到它
ssl_verify: <pathToYourFile>.crt
现在连接那个文件到/miniconda3/ssl/cert.pem
的末尾
和请求应该工作,特别是 sklearn.datasets
和类似的工具
应该可以。
进一步注意事项
其他解决方案无效,因为 Anaconda 设置略有不同:
路径Applications/Python\ 3.X
根本不存在。
下面命令提供的路径是错误的路径
from requests.utils import DEFAULT_CA_BUNDLE_PATH
DEFAULT_CA_BUNDLE_PATH
在我的例子中,我收到此错误是因为 requests
和 urllib3
版本不兼容,在安装过程中出现以下错误:
ERROR: requests 2.21.0 has requirement urllib3<1.25,>=1.21.1, but you'll have urllib3 1.25 which is incompatible.
pip install 'urllib3<1.25' --force-reinstall
成功了。
另一个 Anaconda 解决方案。 我在 macOS 上的 Python 2.7 环境中得到了 CERTIFICATE_VERIFY_FAILED。事实证明 conda 路径是错误的:
基础 (3.7) 环境:
>>> import ssl
>>> ssl.get_default_verify_paths()
DefaultVerifyPaths(cafile='/usr/local/anaconda3/ssl/cert.pem', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/anaconda3/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/anaconda3/ssl/certs')
2.7 环境(路径不存在!):
DefaultVerifyPaths(cafile='', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/anaconda3/envs/py27/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/anaconda3/envs/py27/ssl/certs')
修正:
cd /usr/local/anaconda3/envs/py27/
mkdir ssl
cd ssl
ln -s ../../../ssl/cert.pem
这里已经有很多答案,但是我们 运行 在一个非常具体的案例中对此进行了研究,并且花费了大量时间进行调查,因此又添加了一个。我们在以下案例中看到了它:
- 在 debian-stretch-slim docker 容器中
- 默认Python3.5.3
easy_install3
- 对于在我们的 Kubernetes 集群中使用 cert-manager 注册的 LetsEncrypt 证书
pip3
和 openssl
命令行都能够验证证书并且 easy_install3
能够成功验证其他 LetsEncrypt 证书。
解决方法是从源代码构建最新的 Python(当时是 3.7.3)。说明 here 详细且易于遵循。
我在我的 Linux 机器上遇到了类似的问题。生成新证书并导出指向证书目录的环境变量为我修复了它:
$ sudo update-ca-certificates --fresh
$ export SSL_CERT_DIR=/etc/ssl/certs
$ cd $HOME
$ wget --quiet https://curl.haxx.se/ca/cacert.pem
$ export SSL_CERT_FILE=$HOME/cacert.pem
SSL: CERTIFICATE_VERIFY_FAILED 错误也可能发生,因为 Linux 上的 ca-certificates
包中缺少中间证书。例如,在我的例子中,中间证书“DigiCert SHA2 Secure Server CA”在 ca-certificates
包中丢失,即使 Firefox 浏览器包含它。您可以通过直接在导致此错误的 URL 上 运行ning wget
命令来找出缺少哪个证书。然后,您可以从证书颁发机构的官方网站(例如,在我的示例中为 https://www.digicert.com/digicert-root-certificates.htm)搜索此证书对应的 link 到 CRT 文件。现在,要包含您的案例中缺少的证书,您可以 运行 使用 CRT 文件下载 link 代替以下命令:
wget https://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
mv DigiCertSHA2SecureServerCA.crt DigiCertSHA2SecureServerCA.der
openssl x509 -inform DER -outform PEM -in DigiCertSHA2SecureServerCA.der -out DigicertSHA2SecureServerCA.pem.crt
sudo mkdir /usr/share/ca-certificates/extra
sudo cp DigicertSHA2SecureServerCA.pem.crt /usr/share/ca-certificates/extra/
sudo dpkg-reconfigure ca-certificates
在此之后,您可以使用 wget
再次测试您的 URL 以及使用 python urllib
包。更多详情请参考:https://bugs.launchpad.net/ubuntu/+source/ca-certificates/+bug/1795242
有些情况下您无法使用不安全的连接或将 ssl 上下文传递到 urllib 请求中。这是我的解决方案基于
如果您想使用自己的证书文件
import ssl
def new_ssl_context_decorator(*args, **kwargs):
kwargs['cafile'] = '/etc/ssl/certs/ca-certificates.crt'
return ssl.create_default_context(*args, **kwargs)
ssl._create_default_https_context = ssl._create_unverified_context
或者您可以使用来自 certifi
的共享文件
def new_ssl_context_decorator(*args, **kwargs):
import certifi
kwargs['cafile'] = certifi.where()
return ssl.create_default_context(*args, **kwargs)
如果您有私有证书要处理,例如您的组织拥有 CA 根和链的中间部分,那么最好将证书添加到 ca 文件中。 cacert.pem 比绕过整个安全设备 (verify=False)。下面的代码让你同时使用 2.7+ 和 3+
考虑添加整个证书链,当然你只需要这样做一次。
import certifi
cafile=certifi.where() # cacert file
with open ('rootca.pem','rb') as infile:
customca=infile.read()
with open(cafile,'ab') as outfile:
outfile.write(customca)
with open ('interca.pem','rb') as infile:
customca=infile.read()
with open(cafile,'ab') as outfile:
outfile.write(customca)
with open ('issueca.pem','rb') as infile:
customca=infile.read()
with open(cafile,'ab') as outfile:
outfile.write(customca)
那么这应该让你继续
import requests
response = requests.request("GET", 'https://yoursecuresite.com', data = {})
print(response.text.encode('utf8'))
希望对您有所帮助
我在使用 Python 2.7.9
时遇到了这个问题
这是我所做的:
- 已卸载 Python 2.7.9
- 已删除 c:\Python27 个文件夹
- 已下载 Python 2.7.18,这是今天最新的 Python 2.7 版本。
- 重新运行我的申请
- 成功了!
不再有任何“[CERTIFICATE_VERIFY_FAILED] 证书验证失败 (_ssl.c:581)”错误。
导入请求
response = requests.get("url/api 你想点击", verify="path to ssl certificate")
对我来说,问题是 none 以上答案完全帮助了我,但给了我正确的观察方向。
当然,SSL 证书是必需的,但是当您位于公司的防火墙 后面时,公开可用的证书可能没有帮助p。您可能需要联系公司的 IT 部门以获取证书,因为每家公司都使用从他们签订服务合同的安全提供商处获得的特殊证书。并将它放在一个文件夹中,并将该文件夹的路径作为参数传递给 验证参数。
对我来说,即使尝试了上述所有解决方案并使用了错误的证书,我也无法使其正常工作。所以请记住,那些在公司防火墙后面的人要获得正确的证书。它可以决定您的请求调用的成功与否。
在我的例子中,我将证书放在以下路径中,它就像魔术一样工作。
C:\程序Files\CommonFiles\ssl
你也可以参考https://2.python-requests.org/en/master/user/advanced/#id3里面说的ssl验证
我遇到了同样的错误,并且在我放弃并开始自己尝试之前也进行了很长一段时间的疯狂追逐。我最终弄明白了,所以我想我会分享。就我而言,我在 Linux 上 运行ning Python 2.7.10(由于我无法控制的原因),无法访问请求模块,无法安装证书全局处于 OS 或 Python 级别,无法设置任何环境变量,并且需要访问使用内部颁发的证书的特定内部站点。
注意:禁用 SSL 验证从来不是一种选择。我正在下载一个立即 运行 作为 root 的脚本。如果没有 SSL 验证,任何网络服务器都可以伪装成我的目标主机,我会接受他们给我的任何东西并 运行 它作为 root!
我将根和中间证书(可能有多个)以pem格式保存到一个文件中,然后使用以下代码:
import ssl,urllib2
data = urllib2.build_opener(urllib2.HTTPSHandler(context=ssl.create_default_context(cafile='/path/to/ca-cert-chain.pem')), urllib2.ProxyHandler({})).open('https://your-site.com/somefile').read()
print(data)
请注意,我在此处添加了 urllib2.ProxyHandler({})
。那是因为在我们的环境中,代理是默认设置的,但它们只能访问外部站点,不能访问内部站点。没有代理旁路,我无法访问内部站点。如果你没有那个问题,你可以简化如下:
data = urllib2.build_opener(urllib2.HTTPSHandler(context=ssl.create_default_context(cafile='/path/to/ca-cert-chain.pem'))).open('https://your-site.com/somefile').read()
工作起来很有魅力,而且不会损害安全性。
尽情享受吧!
如果证书是通过 Let's encrypt 颁发的,请确保在客户端的中间证书存储中删除过期的 DST Root CA X3 颁发的 R3
证书。
我的解决方案是使用 Beautiful Soup 一个 python 包。它神奇地处理了 SSL 的东西。 Beautiful Soup 是一个可以轻松从网页中抓取信息的库。
from bs4 import BeautifulSoup as soup
import requests
url = "https://dex.raydium.io/#/market/2xiv8A5xrJ7RnGdxXB42uFEkYHJjszEhaJyKKt4WaLep"
html = requests.get(url, verify=True)
page_soup = soup(html.text, 'html.parser')
print(page_soup.prettify())
我收到以下错误:
Exception in thread Thread-3:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "/Users/Matthew/Desktop/Skypebot 2.0/bot.py", line 271, in process
info = urllib2.urlopen(req).read()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 431, in open
response = self._open(req, data)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 449, in _open
'_open', req)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 409, in _call_chain
result = func(*args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1240, in https_open
context=self._context)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1197, in do_open
raise URLError(err)
URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)>
这是导致此错误的代码:
if input.startswith("!web"):
input = input.replace("!web ", "")
url = "https://domainsearch.p.mashape.com/index.php?name=" + input
req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXX' })
info = urllib2.urlopen(req).read()
Message.Chat.SendMessage ("" + info)
我使用的 API 要求我使用 HTTPS。怎样才能让它绕过验证?
就像我在评论中写的那样,这个问题可能与
简而言之:有多种验证证书的方法。 OpenSSL 使用的验证与您系统上的受信任根证书不兼容。 Python.
使用 OpenSSL您可以尝试为 Verisign Class 3 Public Primary Certification Authority and then use the cafile
option according to the Python documentation 获取丢失的证书:
urllib2.urlopen(req, cafile="verisign.pem")
如果您只是想绕过验证,您可以创建一个新的SSLContext. By default newly created contexts use CERT_NONE。
请注意 17.3.7.2.1
部分所述When calling the SSLContext constructor directly, CERT_NONE is the default. Since it does not authenticate the other peer, it can be insecure, especially in client mode where most of time you would like to ensure the authenticity of the server you’re talking to. Therefore, when in client mode, it is highly recommended to use CERT_REQUIRED.
但是,如果您只是出于其他原因想让它现在工作,您可以执行以下操作,您还必须 import ssl
:
input = input.replace("!web ", "")
url = "https://domainsearch.p.mashape.com/index.php?name=" + input
req = urllib2.Request(url, headers={ 'X-Mashape-Key': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' })
gcontext = ssl.SSLContext() # Only for gangstars
info = urllib2.urlopen(req, context=gcontext).read()
Message.Chat.SendMessage ("" + info)
这应该可以解决您的问题,但您并没有真正解决任何问题,而且您不会看到 [SSL: CERTIFICATE_VERIFY_FAILED]
因为您现在没有验证证书!
除上述内容外,如果您想了解更多关于为什么会看到这些问题的信息,您需要查看 PEP 476。
This PEP proposes to enable verification of X509 certificate signatures, as well as hostname verification for Python's HTTP clients by default, subject to opt-out on a per-call basis. This change would be applied to Python 2.7, Python 3.4, and Python 3.5.
有一个建议选择退出,这与我上面的建议没有什么不同:
import ssl
# This restores the same behavior as before.
context = ssl._create_unverified_context()
urllib.urlopen("https://no-valid-cert", context=context)
它还有一个 非常不推荐 的选项,通过 monkeypatching 你在 python:
中不常看到import ssl
ssl._create_default_https_context = ssl._create_unverified_context
用创建未验证上下文的函数覆盖上下文创建的默认函数。
请注意 PEP 中所述:
This guidance is aimed primarily at system administrators that wish to adopt newer versions of Python that implement this PEP in legacy environments that do not yet support certificate verification on HTTPS connections. For example, an administrator may opt out by adding the monkeypatch above to sitecustomize.py in their Standard Operating Environment for Python. Applications and libraries SHOULD NOT be making this change process wide (except perhaps in response to a system administrator controlled configuration setting).
如果您想阅读有关为什么不验证证书在软件中不好的论文 you can find it here!
和你一样,我在我的旧 iMac (OS X 10.6.8) 上使用 python 2.7,我也遇到了这个问题,使用 urllib2.urlopen :
urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]
我的程序 运行 很好,没有 SSL 证书问题,但突然(在下载程序后),它们因这个 SSL 错误而崩溃。
问题是使用的 python 版本:
https://www.python.org/downloads 和 python-2.7.9-macosx10.6.pkg
没问题
Homebrew tool 安装的问题:"brew install python",版本位于 /usr/local/bin。
Certificate verification and OpenSSL [CHANGED for Python 2.7.9]
中的一章 /Applications/Python 2.7/ReadMe.rtf
详细解释了问题。
所以,检查、下载 python 的正确版本并将其放入您的 PATH 中。
在Windows上,Python不看系统证书,它使用自己位于?\lib\site-packages\certifi\cacert.pem
。
您的问题的解决方案:
- 将域验证证书下载为 *.crt 或 *pem 文件
- 在编辑器中打开文件并将其内容复制到剪贴板
- 找到您的
cacert.pem
位置:from requests.utils import DEFAULT_CA_BUNDLE_PATH; print(DEFAULT_CA_BUNDLE_PATH)
- 编辑
cacert.pem
文件并将您的域验证证书粘贴到文件末尾。 - 保存文件并享受请求!
我半惭愧地低下了头,因为我遇到了同样的问题,除了在我的情况下,我打的 URL 是有效的,证书是有效的。无效的是我与网络的连接。我未能将代理详细信息添加到浏览器(在本例中为 IE)。这阻止了验证过程的正确发生。
添加了代理详细信息,然后我的 python 非常高兴。
如果您使用的是 vCenter 6,您应该将 vCenter 的 vmware 证书颁发机构证书添加到 OS 的受信任 CA 列表中。要下载您的证书,请执行以下操作
- 打开您的网络浏览器。
- 导航至 https://
- 在右下角,单击下载受信任的根 CA link
在 Fedora 上
- 解压缩并将扩展名从 .0 更改为 .cer
- 复制到/etc/pki/ca-trust/source/anchors/
- 运行 update-ca-trust 命令。
链接:
对于 Python 3.4+ on Centos 6/7,Fedora,只需这样安装受信任的 CA :
- 将CA.crt复制到
/etc/pki/ca-trust/source/anchors/
update-ca-trust force-enable
update-ca-trust extract
Python 2.7.12(默认,2016 年 7 月 29 日,15:26:22)修复了上述问题。此信息可能会对其他人有所帮助。
import requests
requests.packages.urllib3.disable_warnings()
import ssl
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context
取自此处https://gist.github.com/michaelrice/a6794a017e349fc65d01
您可以尝试将此添加到您的环境变量中:
PYTHONHTTPSVERIFY=0
请注意,这将禁用所有 HTTPS 验证,因此这是一个有点大锤的方法,但是如果不需要验证,它可能是一个有效的解决方案。
这不是针对您的特定问题的解决方案,但我将其放在这里是因为该帖子是“SSL:CERTIFICATE_VERIFY_FAILED”的最高 Google 结果,它引导我徒劳无功。
如果您在 OSX 上安装了 Python 3.6,并且在尝试连接到 https:// 站点时出现“SSL: CERTIFICATE_VERIFY_FAILED”错误,这可能是因为Python OSX 上的 3.6 根本没有证书,并且无法验证任何 SSL 连接。这是 OSX 上 3.6 的更改,需要 post-install 步骤,安装 certifi
证书包。这记录在生成 macOS 安装程序的文件 ReadMe.rtf, which you can find at /Applications/Python\ 3.6/ReadMe.rtf
(see also the file Conclusion.rtf, and the script build-installer.py
中)。
自述文件将为您提供 运行 /Applications/Python\ 3.6/Install\ Certificates.command
处的 post-install 脚本(其来源为 install_certificates.command
),其中:
- 首先installs the Python package
certifi
,然后 - 然后 creates a symbolic link 从 OpenSSL 证书文件到包
certifi
. 安装的证书文件
发行说明有更多信息:https://www.python.org/downloads/release/python-360/
在 Python 的较新版本中,有更多关于此的文档:
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/ReadMe.rtf#L22-L34
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/Conclusion.rtf#L15-L19
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/Welcome.rtf#L23-L25
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/resources/install_certificates.command
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/README.rst
- https://github.com/python/cpython/blob/e05a703848473b0365886dcc593cbddc46609f29/Mac/BuildScript/build-installer.py#L239-L246
ln -s /usr/local/share/certs/ca-root-nss.crt /etc/ssl/cert.pem
(FreeBSD 10.1
)
尝试
pip install --trusted-host pypi.python.org packagename
它对我有用。
扩展 Craig Glennie 的回答:
在 Python MacOs Sierra 上的 3.6.1
在 bash 终端输入这个解决了问题:
pip install certifi
/Applications/Python\ 3.6/Install\ Certificates.command
我需要添加另一个答案,因为就像 Craig Glennie 一样,由于网络上有很多帖子都提到了这个问题,我开始了疯狂的追逐。
我正在使用 MacPorts,我最初认为是 Python 的问题实际上是 MacPorts 的问题:它在安装 openssl 时没有安装根证书。解决方法是port install curl-ca-bundle
,如this blog post.
看看
/Applications/Python 3.6/Install Certificates.command
您也可以转到 Finder 中的 Applications
文件夹,然后单击 Certificates.command
nltk 的安装步骤(我已经在 MAC OS X
中安装了 python3 (3.6.2)sudo easy_install pip
使用ignore installed 选项来忽略卸载之前版本的六,否则,卸载时会报错并且不会向前播放
sudo pip3 install -U nltk --ignore-installed six
检查 pip 和 python 的安装,使用“3”版本
which python python2 python3
which pip pip2 pip3
检查是否安装了NLTK
python3
import nltk
nltk.__path__
['/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/nltk']
在安装示例书之前安装 SSL 证书,否则在安装示例时我们会出现证书错误
/Applications/Python\ 3.6/Install\ Certificates.command
python3 -m nltk.downloader book
已成功安装 nltk 和 nltk_ata 书籍示例
我很惊讶所有这些说明都没有解决我的问题。尽管如此,诊断是正确的(顺便说一句,我使用的是 Mac 和 Python3.6.1)。因此,总结正确的部分:
- 在 Mac,Apple 将放弃 OpenSSL
- Python 现在使用它自己的一套 CA 根证书
- 二进制Python安装提供了安装CA Root证书的脚本Python需要(/Applications/Python 3.6/Install Certificates.command")
- 阅读“/Applications/Python 3.6/ReadMe.rtf”了解详情
对我来说,脚本不起作用,所有那些 certifi 和 openssl 安装也无法修复。可能是因为我有多个 python 2 和 3 安装,以及许多 virtualenv。最后,我需要手动修复它。
pip install certifi # for your virtualenv
mkdir -p /Library/Frameworks/Python.framework/Versions/3.6/etc/openssl
cp -a <your virtualenv>/site-package/certifi/cacert.pem \
/Library/Frameworks/Python.framework/Versions/3.6/etc/openssl/cert.pem
如果你还是失败了。然后re/install OpenSSL。
port install openssl
我遇到了类似的问题,尽管我在 Python 3.4、3.5 和 3.6 中使用 urllib.request.urlopen
。 (根据 Python 2 的 urllib2
documentation page 开头的注释,这是 Python 3 等同于 urllib2
的一部分。)
我的解决方案是 pip install certifi
安装 certifi
,它有:
... a carefully curated collection of Root Certificates for validating the trustworthiness of SSL certificates while verifying the identity of TLS hosts.
然后,在我之前的代码中:
import urllib.request as urlrq
resp = urlrq.urlopen('https://example.com/bar/baz.html')
我修改为:
import urllib.request as urlrq
import certifi
resp = urlrq.urlopen('https://example.com/bar/baz.html', cafile=certifi.where())
如果我没看错 urllib2.urlopen
documentation,它还有一个 cafile
参数。因此,urllib2.urlopen([...], certifi.where())
也可能适用于 Python 2.7。
更新 (2020-01-01): 从 Python 3.6 开始,the cafile
argument to urlopen
has been deprecated,context
参数应该是指定代替。我发现以下内容在 3.5 到 3.8 上同样有效:
import urllib.request as urlrq
import certifi
import ssl
resp = urlrq.urlopen('https://example.com/bar/baz.html', context=ssl.create_default_context(cafile=certifi.where()))
使用 pip
安装 PyOpenSSL
对我有用(无需转换为 PEM):
pip install PyOpenSSL
我通过关闭 Fiddler(一种 HTTP 调试代理)解决了这个问题,检查您是否启用了代理并重试。
我对 Mac OS X:
的解决方案1) 使用从官方 Python 语言网站下载的本机应用 Python 安装程序升级到 Python 3.6.5 https://www.python.org/downloads/
我发现此安装程序负责更新新 Python 的链接和符号链接,这比自制软件要好得多。
2) 使用刷新后的 Python 3.6 目录
中的“./Install Certificates.command”安装新证书> cd "/Applications/Python 3.6/"
> sudo "./Install Certificates.command"
Python Amazon EC2 上的 2.7 和 centOS 7
我必须将环境变量 SSL_CERT_DIR
设置为指向位于 /etc/ssl/certs/ca-bundle.crt
ca-bundle
In python 2.7 在文件 C:\Python27\lib\site-packages\certifi\cacert.pem 的末尾添加受信任的根 CA 详细信息帮助
之后我做了 运行(使用管理员权限) pip install --trusted-host pypi.python.org --trusted-host pypi.org --trusted-host files.pythonhosted.org packageName
对于遇到此问题的使用 mechanize
的任何人,以下是如何将相同技术应用于机械化浏览器实例的方法:
br = mechanize.Browser()
context = ssl._create_unverified_context()
br.set_ca_data(context=context)
在 Mac 上安装 certifi 解决了我的问题:
pip install certifi
我在 here
上找到了这个我找到了这个解决方案,在源文件的开头插入这段代码:
import ssl
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context
这段代码取消了验证,因此不验证ssl认证。
对于 Linux Python3.6,这对我有用。
从命令行安装 pyopenssl 和 certifi
sudo pip3 install -U pyopenssl
sudo pip3 install certifi
并且在我的 python3 脚本中,添加了 verify='/usr/lib/python3.6/site-packages/certifi/cacert.pem' 像这样:
import requests
from requests.auth import HTTPBasicAuth
import certifi
auth = HTTPBasicAuth('username', 'password')
body = {}
r = requests.post(url='https://your_url.com', data=body, auth=auth, verify='/usr/lib/python3.6/site-packages/certifi/cacert.pem')
Anaconda 的解决方案
我的设置是 Anaconda Python MacOS 上的 3.7 代理。路径不同。
- 这就是您获得正确证书路径的方式:
import ssl
ssl.get_default_verify_paths()
在我的系统上产生了
Out[35]: DefaultVerifyPaths(cafile='/miniconda3/ssl/cert.pem', capath=None,
openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/miniconda3/ssl/cert.pem',
openssl_capath_env='SSL_CERT_DIR', openssl_capath='/miniconda3/ssl/certs')
一旦您知道证书的去向,您就可以将代理使用的证书连接到该文件的末尾。
我已经通过 运行 设置了 conda 来使用我的代理:
conda config --set ssl_verify <pathToYourFile>.crt
如果您不记得您的证书在哪里,您可以在 ~/.condarc
:
ssl_verify: <pathToYourFile>.crt
现在连接那个文件到/miniconda3/ssl/cert.pem
的末尾
和请求应该工作,特别是 sklearn.datasets
和类似的工具
应该可以。
进一步注意事项
其他解决方案无效,因为 Anaconda 设置略有不同:
路径
Applications/Python\ 3.X
根本不存在。下面命令提供的路径是错误的路径
from requests.utils import DEFAULT_CA_BUNDLE_PATH
DEFAULT_CA_BUNDLE_PATH
在我的例子中,我收到此错误是因为 requests
和 urllib3
版本不兼容,在安装过程中出现以下错误:
ERROR: requests 2.21.0 has requirement urllib3<1.25,>=1.21.1, but you'll have urllib3 1.25 which is incompatible.
pip install 'urllib3<1.25' --force-reinstall
成功了。
另一个 Anaconda 解决方案。 我在 macOS 上的 Python 2.7 环境中得到了 CERTIFICATE_VERIFY_FAILED。事实证明 conda 路径是错误的:
基础 (3.7) 环境:
>>> import ssl
>>> ssl.get_default_verify_paths()
DefaultVerifyPaths(cafile='/usr/local/anaconda3/ssl/cert.pem', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/anaconda3/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/anaconda3/ssl/certs')
2.7 环境(路径不存在!):
DefaultVerifyPaths(cafile='', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/local/anaconda3/envs/py27/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/local/anaconda3/envs/py27/ssl/certs')
修正:
cd /usr/local/anaconda3/envs/py27/
mkdir ssl
cd ssl
ln -s ../../../ssl/cert.pem
这里已经有很多答案,但是我们 运行 在一个非常具体的案例中对此进行了研究,并且花费了大量时间进行调查,因此又添加了一个。我们在以下案例中看到了它:
- 在 debian-stretch-slim docker 容器中
- 默认Python3.5.3
easy_install3
- 对于在我们的 Kubernetes 集群中使用 cert-manager 注册的 LetsEncrypt 证书
pip3
和 openssl
命令行都能够验证证书并且 easy_install3
能够成功验证其他 LetsEncrypt 证书。
解决方法是从源代码构建最新的 Python(当时是 3.7.3)。说明 here 详细且易于遵循。
我在我的 Linux 机器上遇到了类似的问题。生成新证书并导出指向证书目录的环境变量为我修复了它:
$ sudo update-ca-certificates --fresh
$ export SSL_CERT_DIR=/etc/ssl/certs
$ cd $HOME
$ wget --quiet https://curl.haxx.se/ca/cacert.pem
$ export SSL_CERT_FILE=$HOME/cacert.pem
SSL: CERTIFICATE_VERIFY_FAILED 错误也可能发生,因为 Linux 上的 ca-certificates
包中缺少中间证书。例如,在我的例子中,中间证书“DigiCert SHA2 Secure Server CA”在 ca-certificates
包中丢失,即使 Firefox 浏览器包含它。您可以通过直接在导致此错误的 URL 上 运行ning wget
命令来找出缺少哪个证书。然后,您可以从证书颁发机构的官方网站(例如,在我的示例中为 https://www.digicert.com/digicert-root-certificates.htm)搜索此证书对应的 link 到 CRT 文件。现在,要包含您的案例中缺少的证书,您可以 运行 使用 CRT 文件下载 link 代替以下命令:
wget https://cacerts.digicert.com/DigiCertSHA2SecureServerCA.crt
mv DigiCertSHA2SecureServerCA.crt DigiCertSHA2SecureServerCA.der
openssl x509 -inform DER -outform PEM -in DigiCertSHA2SecureServerCA.der -out DigicertSHA2SecureServerCA.pem.crt
sudo mkdir /usr/share/ca-certificates/extra
sudo cp DigicertSHA2SecureServerCA.pem.crt /usr/share/ca-certificates/extra/
sudo dpkg-reconfigure ca-certificates
在此之后,您可以使用 wget
再次测试您的 URL 以及使用 python urllib
包。更多详情请参考:https://bugs.launchpad.net/ubuntu/+source/ca-certificates/+bug/1795242
有些情况下您无法使用不安全的连接或将 ssl 上下文传递到 urllib 请求中。这是我的解决方案基于
如果您想使用自己的证书文件
import ssl
def new_ssl_context_decorator(*args, **kwargs):
kwargs['cafile'] = '/etc/ssl/certs/ca-certificates.crt'
return ssl.create_default_context(*args, **kwargs)
ssl._create_default_https_context = ssl._create_unverified_context
或者您可以使用来自 certifi
的共享文件def new_ssl_context_decorator(*args, **kwargs):
import certifi
kwargs['cafile'] = certifi.where()
return ssl.create_default_context(*args, **kwargs)
如果您有私有证书要处理,例如您的组织拥有 CA 根和链的中间部分,那么最好将证书添加到 ca 文件中。 cacert.pem 比绕过整个安全设备 (verify=False)。下面的代码让你同时使用 2.7+ 和 3+
考虑添加整个证书链,当然你只需要这样做一次。
import certifi
cafile=certifi.where() # cacert file
with open ('rootca.pem','rb') as infile:
customca=infile.read()
with open(cafile,'ab') as outfile:
outfile.write(customca)
with open ('interca.pem','rb') as infile:
customca=infile.read()
with open(cafile,'ab') as outfile:
outfile.write(customca)
with open ('issueca.pem','rb') as infile:
customca=infile.read()
with open(cafile,'ab') as outfile:
outfile.write(customca)
那么这应该让你继续
import requests
response = requests.request("GET", 'https://yoursecuresite.com', data = {})
print(response.text.encode('utf8'))
希望对您有所帮助
我在使用 Python 2.7.9
时遇到了这个问题这是我所做的:
- 已卸载 Python 2.7.9
- 已删除 c:\Python27 个文件夹
- 已下载 Python 2.7.18,这是今天最新的 Python 2.7 版本。
- 重新运行我的申请
- 成功了!
不再有任何“[CERTIFICATE_VERIFY_FAILED] 证书验证失败 (_ssl.c:581)”错误。
导入请求
response = requests.get("url/api 你想点击", verify="path to ssl certificate")
对我来说,问题是 none 以上答案完全帮助了我,但给了我正确的观察方向。
当然,SSL 证书是必需的,但是当您位于公司的防火墙 后面时,公开可用的证书可能没有帮助p。您可能需要联系公司的 IT 部门以获取证书,因为每家公司都使用从他们签订服务合同的安全提供商处获得的特殊证书。并将它放在一个文件夹中,并将该文件夹的路径作为参数传递给 验证参数。
对我来说,即使尝试了上述所有解决方案并使用了错误的证书,我也无法使其正常工作。所以请记住,那些在公司防火墙后面的人要获得正确的证书。它可以决定您的请求调用的成功与否。
在我的例子中,我将证书放在以下路径中,它就像魔术一样工作。
C:\程序Files\CommonFiles\ssl
你也可以参考https://2.python-requests.org/en/master/user/advanced/#id3里面说的ssl验证
我遇到了同样的错误,并且在我放弃并开始自己尝试之前也进行了很长一段时间的疯狂追逐。我最终弄明白了,所以我想我会分享。就我而言,我在 Linux 上 运行ning Python 2.7.10(由于我无法控制的原因),无法访问请求模块,无法安装证书全局处于 OS 或 Python 级别,无法设置任何环境变量,并且需要访问使用内部颁发的证书的特定内部站点。
注意:禁用 SSL 验证从来不是一种选择。我正在下载一个立即 运行 作为 root 的脚本。如果没有 SSL 验证,任何网络服务器都可以伪装成我的目标主机,我会接受他们给我的任何东西并 运行 它作为 root!
我将根和中间证书(可能有多个)以pem格式保存到一个文件中,然后使用以下代码:
import ssl,urllib2
data = urllib2.build_opener(urllib2.HTTPSHandler(context=ssl.create_default_context(cafile='/path/to/ca-cert-chain.pem')), urllib2.ProxyHandler({})).open('https://your-site.com/somefile').read()
print(data)
请注意,我在此处添加了 urllib2.ProxyHandler({})
。那是因为在我们的环境中,代理是默认设置的,但它们只能访问外部站点,不能访问内部站点。没有代理旁路,我无法访问内部站点。如果你没有那个问题,你可以简化如下:
data = urllib2.build_opener(urllib2.HTTPSHandler(context=ssl.create_default_context(cafile='/path/to/ca-cert-chain.pem'))).open('https://your-site.com/somefile').read()
工作起来很有魅力,而且不会损害安全性。
尽情享受吧!
如果证书是通过 Let's encrypt 颁发的,请确保在客户端的中间证书存储中删除过期的 DST Root CA X3 颁发的 R3
证书。
我的解决方案是使用 Beautiful Soup 一个 python 包。它神奇地处理了 SSL 的东西。 Beautiful Soup 是一个可以轻松从网页中抓取信息的库。
from bs4 import BeautifulSoup as soup
import requests
url = "https://dex.raydium.io/#/market/2xiv8A5xrJ7RnGdxXB42uFEkYHJjszEhaJyKKt4WaLep"
html = requests.get(url, verify=True)
page_soup = soup(html.text, 'html.parser')
print(page_soup.prettify())