我在使用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)
...
如果指定的协议与我正在尝试访问的网站匹配,那将会有效。但是,这似乎不是最好的解决方案,因为:
有没有人知道适用于每个TLS版本的通用解决方案?我在这里错过了什么吗?
PS:为了完整起见,我将补充说我使用的是Debian 9,python v3.6.2,openssl v1.1.0f和urllib3 v1.22
答案 0 :(得分:0)
最后,我选择将方法调用包装在try-except中,因此我可以使用较旧的SSL版本作为后备。最终的代码是:
{{1}}
我只在十几个网站上测试了这个代码,到目前为止它似乎有效,但我不确定它每次都会有效。此外,这个解决方案似乎效率低下,因为它需要两个http请求,这可能非常慢。
仍然欢迎改进:)