Python Requests SSL问题

8

我已经花了好几天时间寻找这个问题的解决方案。

我一直尝试使用requests通过代理进行https请求,但是没有成功。

虽然这是我一个更大项目的一部分,但最终都归结为这个问题:

    import requests

    prox = 'xxx.xxx.xxx.xxx:xxx' # fill in valid proxy

    r = requests.get('https://ipdb.at', proxies={'http': prox,
                                                 'https': prox})

我尝试了kward verify=False,但是我一直得到相同的错误或者它的变体:
    Traceback (most recent call last):
      File "/Users/mg/Desktop/proxy_service.py", line 21, in <module>
        verify=False)
      File "/Library/Python/2.7/site-packages/requests/api.py", line 55, in get
        return request('get', url, **kwargs)
      File "/Library/Python/2.7/site-packages/requests/api.py", line 44, in request
        return session.request(method=method, url=url, **kwargs)
      File "/Library/Python/2.7/site-packages/requests/sessions.py", line 279, in request
        resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
      File "/Library/Python/2.7/site-packages/requests/sessions.py", line 374, in send
        r = adapter.send(request, **kwargs)
      File "/Library/Python/2.7/site-packages/requests/adapters.py", line 213, in send
        raise SSLError(e)
    requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
    [Finished in 20.4s with exit code 1]

我正在使用最新版本的requests和openssl以及Python的2.7.3版本。我在Mac Mountain Lion 10.8.2和Windows Seven上进行了测试。
我在谷歌上搜索了一下,发现其他人也遇到了类似的问题。我找到了与requests和urllib3库相关的拉取请求,并且还看到了关于这个问题是http连接动词实现不好的信息。我找到了一个解决方法,使用自定义适配器(我记不清确切术语了,但我认为这是正确的术语)来使用自定义的SSL协议。我尝试了所有的方法,但都没有帮助。
所以,我正在寻找更多的信息。你有任何想法吗?我能修复它吗?
欢迎提供任何帮助。
我尝试了几个代理,我确定它们不是问题的原因。

这可能会有所帮助:http://stackoverflow.com/questions/13463206/how-to-get-https-content-using-python-requests-through-tor-and-privoxy?rq=1 - Timothy Corbett-Clark
看起来 urllib3 快要支持这个了:https://github.com/shazow/urllib3/pull/139。 - Simon Weber
2个回答

16

我曾经遇到过同样的问题,当时我试图使用oauth2client(Google用于访问其API的库)进行认证。在经过一天的“尝试”后,我发现我的环境变量已设置如下:

https_proxy=https://your-proxy:port

将此更改为

https_proxy=http://your-proxy:port

对我来说,完全解决了我的问题。据推测,这意味着从客户端到代理服务器的初始握手现在未加密,但在此之后,https必须直接传输。我不认为我的公司代理配置为使用https通信。

请注意,以前的设置下,我的所有浏览器都能正常工作。也许它们在无法使用https时静默地尝试通过http建立代理连接。

Google搜索显示,https_proxy的设置示例既可以是http地址,也可以是https地址。我想这取决于代理的配置方式。

浏览器/操作系统配置弹出窗口中的“所有协议均使用”按钮很容易让人误用我之前的设置。

但是我不确定那是否是你的问题。你的代码表明你已经完全使用相同的代理设置来处理http和https请求。

顺便说一下,这全部是在Ubuntu 12.04.1上完成的。


请停止发布和删除。您应该能够看到已删除的帖子,然后进行编辑并取消删除。 - Shadow The Spring Wizard
这对我有用。我不知道是否适用于https协议的任何代理,但如果是这样,requests库应该能够自动检测和纠正此问题。 - Roman Rdgz

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接