我得到以下错误:

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


当前回答

在Mac上安装证书解决了我的问题:

pip install certifi

其他回答

我在这里找到了这个

我找到了这个解决方案,在你的源文件开始插入这段代码:

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证书。

如果证书是通过Let's encrypt颁发的,请确保在客户机上的中间证书存储中删除过期的DST根CA X3颁发的R3证书。

我对Mac OS X的解决方案:

使用从Python语言官方网站https://www.python.org/downloads/下载的本地应用程序Python安装程序升级到Python 3.6.5

我发现这个安装程序在更新新Python的链接和符号链接方面比自制的要好得多。

使用"安装新证书。/Install Certificates.command”,该命令位于刷新后的Python 3.6目录中

cd "/Applications/Python 3.6/"
sudo "./Install Certificates.command"

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

pip install PyOpenSSL

I was getting the same error, and also went on a wild goose chase for quite a while before I gave up and started trying things on my own. I eventually figured it out, so I thought I'd share. In my case, I am running Python 2.7.10 (due to reasons beyond my control) on Linux, don't have access to the requests module, can't install certificates globally at the OS or Python level, can't set any environment variables, and need to access a specific internal site that uses internally issued certificates.

注意:禁用SSL验证从来不是一个选项。我正在下载一个脚本,它可以立即以根用户的身份运行。没有SSL验证,任何web服务器都可以假装是我的目标主机,而我只是接受他们给我的任何东西,并以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()

工作起来很有魅力,而且不会危及安全。

享受吧!