通过NTLM代理使用urllib2时HTTPS请求失败

0 投票
1 回答
3373 浏览
提问于 2025-04-18 14:14

我通过Python的urllib2想在公司内部的NTLM代理后获取HTTPS数据。

我运行了

proxy_url = ('http://user:pw@ntlmproxy:port/')
proxy_handler = urllib2.ProxyHandler({'http': proxy_url})
opener = urllib2.build_opener(proxy_handler, urllib2.HTTPHandler)
urllib2.install_opener(opener)

f = urllib2.urlopen('https://httpbin.org/ip')
myfile = f.read()
print myfile

但出现了错误

urllib2.URLError: <urlopen error [Errno 8] _ssl.c:507: 
EOF occurred in violation of protocol>

我该如何解决这个错误呢?

注意 0: 用同样的代码,我可以获取不安全的HTTP版本 http://httpbin.org/ip

注意 1: 在普通浏览器中,我可以通过同一个公司代理访问 https://httpbin.org/ip(还有其他HTTPS网站)。

注意 2: 我在网上看到很多类似的问题,有人提到这可能和证书验证有关,但urllib2其实并不验证证书。

注意 3: 有些人在类似情况下建议使用猴子补丁,但我想,似乎没有办法对_ssl.c进行猴子补丁。

1 个回答

0

问题在于,Python的标准HTTP库并不能完全支持微软的NTLM认证协议。

我通过设置一个本地的支持NTLM的代理解决了这个问题——ntlmaps对我来说就很有效。(*)——这个代理可以处理公司网络的认证,然后我把我的Python代码指向这个本地代理,而不需要提供认证信息。

另外,我还需要在上面提到的Python代码中添加一个用于HTTPS的代理处理器。所以我把这两行

proxy_url = 'http://user:pw@ntlmproxy:port/' 
proxy_handler = urllib2.ProxyHandler({'http': proxy_url})

替换成这两行

proxy_url = 'http://localproxy:localport/' 
proxy_url_https = 'https://localproxy:localport/' 
proxy_handler = urllib2.ProxyHandler({'http': proxy_url, 'https': proxy_url_https})

这样请求就能正常工作了。


(*) ntlmaps是一个Python程序。由于我个人环境的一些原因,我需要这个代理是一个Python程序。)

撰写回答