Python 3 urllib 忽略 SSL 证书验证

46

我设置了一个用于测试的服务器,使用了自签名证书,并希望能够对其进行测试。

如何在Python 3版本的urlopen中忽略SSL验证?

我找到的所有信息都涉及到urllib2或Python 2。

在Python 3中,urllib已经从urllib2改变:

Python 2,urllib2:urllib2.urlopen(url[, data[, timeout[, cafile[, capath[, cadefault[, context]]]]]])

https://docs.python.org/2/library/urllib2.html#urllib2.urlopen

Python 3:urllib.request.urlopen(url[, data][, timeout]) https://docs.python.org/3.0/library/urllib.request.html?highlight=urllib#urllib.request.urlopen

所以我知道这可以在Python 2中以下面的方式完成。然而,Python 3的urlopen缺少上下文参数。

import urllib2
import ssl

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

urllib2.urlopen("https://your-test-server.local", context=ctx)

是的,我知道这是一个糟糕的想法。这只是为了在私人服务器上进行测试。

我在Python 3文档中找不到相关方法,其他问题也没有提供解决方案。即使是明确提及Python 3的问题,也仍然提供urllib2/Python 2的解决方案。


可能是如何在Python 3.x中禁用SSL检查?的重复问题。 - nngeek
3个回答

67

被接受的答案只是建议使用Python 3.5+,而不是直接回答问题。这会导致困惑。

对于寻求直接答案的人,这就是答案:

import ssl
import urllib.request

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

with urllib.request.urlopen(url_string, context=ctx) as f:
    f.read(300)

或者,如果您使用 requests 库,它具有更好的API:

import requests

with open(file_name, 'wb') as f:
    resp = requests.get(url_string, verify=False)
    f.write(resp.content)

答案来自于这篇帖子 (感谢 @falsetru): 如何在 Python 3.x 中禁用 SSL 检查?

这两个问题应该合并。


1
我在使用“requests”库时设置了verify = False,然后发现我现在从urllib3收到了很多警告,这使得在开发过程中阅读我的一些日志变得困难。如果有人遇到这个问题,请参考urllib3文档的这一部分 - RemedialBear

6

Python 3.0到3.3没有上下文参数,该参数在Python 3.4中添加。因此,您可以将Python版本更新到3.5以使用上下文。


21
你可以更改默认上下文:ssl._create_default_https_context = ssl._create_unverified_context,这样你就不需要ctx了。 - AstraSerg
3
感谢@AstraSerg,我认为你的评论值得转化为一个独立的回答。 - piit79

0
您可以在创建PoolManager或ProxyManager对象时指定cert_reqs='CERT_NONE'。
例如:
proxy = urllib3.ProxyManager("https://localhost:8443", cert_reqs='CERT_NONE')

或者

pool = urllib3.PoolManager(cert_reqs='CERT_NONE')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接