我得到以下错误:

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


当前回答

我也遇到了类似的问题,不过我在Python 3.4、3.5和3.6中使用了urllib.request.urlopen。(这是Python 3中urllib2的一部分,根据Python 2的urllib2文档页面头部的注释。)

我的解决方案是pip install certifi来安装certifi,它有:

... 一个精心策划的根证书集合,用于验证SSL证书的可信度,同时验证TLS主机的身份。

然后,在我的代码中,我之前只有:

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文档正确,它也有一个cafile参数。所以,urllib2.urlopen([…], certificate .where())可能也适用于Python 2.7。


更新(2020-01-01):自Python 3.6起,已弃用urlopen的cafile参数,取而代之的应该是指定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()))

其他回答

在我的情况下,我得到这个错误,因为请求和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

成功了。

如果你在vCenter 6上,你应该将你vCenter的vmware证书颁发机构证书添加到你的操作系统的受信任CA列表中。要下载证书,请执行以下操作

打开Web浏览器。 导航到https:// 在右下角单击“下载受信任的根CA”链接

在Fedora

解压缩并将扩展名从.0更改为.cer 将其复制到/etc/pki/ca-trust/source/anchors/ 执行update-ca-trust命令。

链接:

https://virtualizationreview.com/articles/2015/04/02/install-root-self-signed-certificate-vcenter-6.aspx?m=1 http://forums.fedoraforum.org/showthread.php?t=293856

我在Python 2.7.9中遇到了这个问题

以下是我所做的:

卸载Python 2.7.9 删除c:\Python27文件夹 下载了Python 2.7.18,这是今天最新发布的Python 2.7。 重新运行应用程序 它成功了!

不再有任何“[CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:581)”错误。

有些情况下,你不能使用不安全的连接或传递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)

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