【发布时间】:2018-04-02 18:21:54
【问题描述】:
我在使用 urllib 在我的 Debian 服务器上获取一些 Web 内容时遇到了一些问题。我使用以下代码可以毫无问题地获取大多数网站的内容:
import urllib.request as request
url = 'https://www.metal-archives.com/'
req = request.Request(url, headers={'User-Agent': "foobar"})
response = request.urlopen(req)
response.read()
但是,如果网站使用的是较旧的加密协议,urlopen 函数将抛出以下错误:
ssl.SSLError: [SSL: VERSION_TOO_LOW] version too low (_ssl.c:748)
我找到了解决此问题的方法,包括使用 SSL 上下文并将其作为参数传递给 urlopen 函数,因此必须修改之前的代码:
...
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
response = request.urlopen(req, context=context)
...
只要指定的协议与我尝试访问的网站匹配,这将起作用。然而,这似乎不是最好的解决方案,因为:
- 如果网站所有者更新了他们的加密方法,代码将停止工作
- 上面的代码只适用于这个网站,我必须为我在整个程序中访问的每个网站创建特殊情况,因为每个人都可能使用不同版本的协议。这会导致代码非常混乱
- 我发布的第一个解决方案(没有 ssl 上下文的解决方案)奇怪地似乎在我的 ArchLinux 机器上工作,即使它们的所有版本都相同
有人知道适用于每个 TLS 版本的通用解决方案吗?我在这里遗漏了什么吗?
PS:为了完整起见,我会补充说我正在使用 Debian 9、python v3.6.2、openssl v1.1.0f 和 urllib3 v1.22
【问题讨论】:
标签: python ssl urllib python-3.6