urllib 和“SSL:CERTIFICATE_VERIFY_FAILED”错误

新手上路,请多包涵

我收到以下错误:

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

原文由 user3724476 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 628
2 个回答

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

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

直接调用 SSLContext 构造函数时,CERT_NONE 是默认值。由于它不对其他对等方进行身份验证,因此它可能是不安全的,尤其是在客户端模式下,在大多数情况下您希望确保正在与之交谈的服务器的真实性。因此,在客户端模式下,强烈建议使用 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

此 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 中所述:

本指南主要针对希望采用较新版本的 Python 以在尚不支持 HTTPS 连接上的证书验证的旧环境中实现此 PEP 的系统管理员。例如,管理员可以通过将上面的 monkeypatch 添加到他们的 Python 标准操作环境中的 sitecustomize.py 来选择退出。 应用程序和库不应该在整个过程中进行这种更改(除非可能是为了响应系统管理员控制的配置设置)。

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

原文由 Noelkd 发布,翻译遵循 CC BY-SA 4.0 许可协议

这不是针对您的特定问题的解决方案,但我将其放在这里是因为该线程是“SSL:CERTIFICATE_VERIFY_FAILED”的 Google 最高搜索结果,它让我陷入了疯狂的追逐。

如果您在 OSX 上安装了 Python 3.6 并且在尝试连接到 https:// 站点时收到“SSL: CERTIFICATE_VERIFY_FAILED”错误,这可能是因为 OSX 上的 Python 3.6 根本没有证书,并且无法验证任何 SSL连接。这是 OSX 上 3.6 的更改,需要安装后步骤,即安装 certifi 证书包。这记录在文件 ReadMe.rtf 中,您可以在 /Applications/Python\ 3.6/ReadMe.rtf 找到(另请参见文件 Conclusion.rtf 和生成 macOS 安装程序的脚本 build-installer.py )。

自述文件会让您在以下位置运行安装后脚本

/Applications/Python\ 3.10/Install\ Certificates.command (终端应用程序,仅此命令就可以解决问题。请务必使用当前的子版本更新文件路径。)

(其来源是 install_certificates.command ),其中:

发行说明有更多信息: https ://www.python.org/downloads/release/python-360/

在较新版本的 Python 上,有更多关于此的文档:

原文由 Craig Glennie 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题