【问题标题】:How do I disable the ssl check in python 3.x?如何在 python 3.x 中禁用 ssl 检查?
【发布时间】:2015-11-18 01:15:26
【问题描述】:

我正在使用 urllib.request.urlretrieve 将文件下载到本地。

urllib.request.urlretrieve(url_string,file_name)

它抛出错误:

ssl.CertificateError 未被用户代码处理 消息:主机名 'foo.net' 与 'a248.e.akamai.net'、'.akamaihd.net'、'.akamaihd-staging.net'、'.akamaized.net','.akamaized-staging.net'

如果您将 url 复制到 Chrome 中,它会向您显示一条通知,您需要说“继续访问该 url”之类的内容。

【问题讨论】:

标签: python python-3.x ssl


【解决方案1】:

urllib.request.urlopencustom ssl context 一起使用:

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 u, \
        open(file_name, 'wb') as f:
    f.write(u.read())

或者,如果你使用requests library,它可能更简单:

import requests

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

【讨论】:

  • 我猜第一个解决方案有一些错字,这很好用:D with urllib.request.urlopen(url_string, context=ctx) as u: f = open(file_name, 'wb') f.write(u.read()) 不确定 Python3 中是否有 requests 库
  • @BingGan,我修正了错字。感谢您的反馈意见。 requests 支持 Python 3.x。 pip install requests 和受益。 :)
  • 即使在设置了check_hostname=False 之后,我也会收到Cannot set verify_mode to CERT_NONE when check_hostname is enabled.。有什么想法吗?
  • 好的,所以我们必须在verify_mode之前设置check_hostname
  • shutil.copyfileobj(u, f) 可以用来代替f.write(u.read()),以避免将整个内容加载到内存中。
【解决方案2】:

函数 urllib.request.urlretrieve 不接受任何 SSL 选项,但 urllib.request.urlopen 接受。

但是,您可以使用 ssl.create_default_context() 创建不安全的上下文,而不是使用 ssl.create_default_context() 创建安全的 SSL 上下文:

这个:

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

相当于:

ctx = ssl.SSLContext()

(对于 Python ssl.SSLContext(ssl.PROTOCOL_TLSv1))

这是一个很好的单线:

import ssl
import urllib.request

with urllib.request.urlopen("https://wrong.host.badssl.com/", context=ssl.SSLContext()) as url:
    print(url.read())

【讨论】:

  • ctx(第一个版本)给出了不受支持的协议。
  • @JamesHirschorn 你是什么意思?你是怎么得到这个错误的?
  • 我在使用您的代码时遇到了该错误,第一个定义为 ctx,并且 URL 不同。所以:使用 urllib.request.urlopen(my_url, context=ctx) as url: print(url.read()) 我猜该网站可能不支持最近的协议,即使证书验证已关闭?
  • 是的,这个技巧是禁用证书的特定检查。协议和密码仍然必须匹配。
猜你喜欢
  • 1970-01-01
  • 2017-02-16
  • 1970-01-01
  • 2021-09-05
  • 2016-09-28
  • 2011-07-19
  • 2016-11-16
  • 1970-01-01
  • 2014-06-23
相关资源
最近更新 更多