我得到以下错误:

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


当前回答

Craig Glennie的回答是:

MacOs Sierra上的Python 3.6.1

在bash终端中输入这个可以解决问题:

pip install certifi
/Applications/Python\ 3.6/Install\ Certificates.command

其他回答

我很惊讶所有这些指导都没有解决我的问题。尽管如此,诊断是正确的(顺便说一句,我使用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

像你一样,我在我的旧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工具安装的“brew install python”有问题,版本位于/usr/local/bin。

在/Applications/Python 2.7/ReadMe.rtf中,有一章名为证书验证和OpenSSL[已更改为Python 2.7.9],详细解释了这个问题。

因此,检查,下载并将正确版本的python放入您的PATH中。

在python 2.7中,在文件C:\Python27\lib\site-packages\certifi\cacert中添加受信任根CA的详细信息。pem帮助

之后我运行(使用管理员权限) pip install——truste- host pypi.python.org——truste- host pypi.org——truste- host files.pythonhosted.org packageName

使用pip安装PyOpenSSL对我来说是有效的(没有转换为PEM):

pip install PyOpenSSL

如果只想绕过验证,可以创建一个新的SSLContext。默认情况下,新创建的上下文使用CERT_NONE。

如17.3.7.2.1节所述,请注意这一点

当直接调用SSLContext构造函数时,CERT_NONE是默认值。由于它不验证另一个对等体,因此它可能是不安全的,特别是在客户端模式下,大多数时候您希望确保与之通信的服务器的真实性。因此,在客户端模式下,强烈建议使用CERT_REQUIRED。

但如果你只是想让它现在工作,你可以做以下事情,你也必须导入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。

这个PEP建议在默认情况下启用X509证书签名的验证,以及Python的HTTP客户端的主机名验证,并在每次调用的基础上选择退出。此更改将应用于Python 2.7、Python 3.4和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).

如果你想读一篇关于为什么不验证证书是不好的软件的论文,你可以在这里找到它!