我在使用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、pythonv3.6.2、OpenSSLv1.1.0f和urllib3 v1.22
发布于 2018-01-16 22:10:28
最后,我选择将方法调用包装在一个try-除了,所以我可以使用旧的SSL版本作为后盾。最后的代码是:
url = 'https://www.metal-archives.com'
req = request.Request(url, headers={"User-Agent": "foobar"})
try:
response = request.urlopen(req)
except (ssl.SSLError, URLError):
# Try to use the older TLSv1 to see if we can fix the problem
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
response = request.urlopen(req, context=context)我只在十几个网站上测试过这个代码,到目前为止它似乎还能工作,但我不确定它每次都会起作用。而且,这个解决方案似乎效率低下,因为它需要两个http请求,这可能非常慢。
(仍欢迎改进:)
https://stackoverflow.com/questions/46868413
复制相似问题