我得到以下错误:

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。我怎样才能让它绕过验证呢?


当前回答

在Windows上,Python不会查看系统证书,它使用自己的位于?\lib\site-packages\certifi\cacert.pem的证书。

问题的解决方案:

下载“*”格式的域验证证书。CRT或*pem文件 在编辑器中打开文件并将其内容复制到剪贴板 找到你的cacert。Pem位置:来自请求。导入DEFAULT_CA_BUNDLE_PATH;打印(DEFAULT_CA_BUNDLE_PATH) 编辑cacert。Pem文件,并将您的域验证证书粘贴在文件的末尾。 保存文件并享受请求!

其他回答

我很惊讶所有这些指导都没有解决我的问题。尽管如此,诊断是正确的(顺便说一句,我使用Mac和Python3.6.1)。所以,总结一下正确的部分:

在Mac上,苹果放弃了OpenSSL Python现在使用它自己的CA根证书集 二进制Python安装提供了一个脚本来安装Python所需的CA根证书("/Applications/Python 3.6/ install Certificates.command") 详细信息请阅读“/Applications/Python 3.6/ReadMe.rtf”

对我来说,脚本不能工作,所有那些证书和openssl安装也未能修复。也许是因为我安装了多个python2和python3,以及许多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

如果你还不满意的话。然后重新安装OpenSSL。

port install openssl

Python 2.7.12(默认,2016年7月29日,15:26:22)修复了上述问题。这个信息可能会帮助到其他人。

另一个水蟒解决方案。我在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 environment(路径不存在!)

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

这里已经有很多答案了,但我们在一个非常具体的案例中遇到了这个问题,花了很多时间调查,所以再加一个。我们在下面的例子中看到:

在一个德比安式细长的码头集装箱里 默认Python 3.5.3 easy_install3 对于在Kubernetes集群中使用cert-manager注册的LetsEncrypt证书

pip3和openssl命令行都能够验证该证书,easy_install3能够成功验证其他LetsEncrypt证书。

解决办法是从源代码构建最新的Python(当时是3.7.3)。这里的说明很详细,很容易理解。

有些情况下,你不能使用不安全的连接或传递ssl上下文到urllib请求。这里我的解决方案基于 https://stackoverflow.com/a/28052583/6709778

在这种情况下,如果您想使用自己的证书文件

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)