【问题标题】:Python Requests library can't handle redirects for HTTPS URLs when behind a proxy在代理后面时,Python 请求库无法处理 HTTPS URL 的重定向
【发布时间】:2013-12-24 14:55:48
【问题描述】:

我想我在使用 HTTPS 时发现了 Requests 库处理重定向的问题。据我所知,这只是服务器将 Requests 客户端重定向到另一个 HTTPS 资源时的问题。

我可以向您保证,我使用的代理支持 HTTPS 和 CONNECT 方法,因为我可以在浏览器中使用它。我正在使用 2.1.0 版的 Requests 库,它正在使用 1.7.1 版的 urllib3 库。

我在wireshark 中查看了交易,我可以看到https://www.paypal.com/ 的第一笔交易,但我没有看到https://www.paypal.com/home 的任何内容。使用调试器在堆栈中进行更深的调试时,我不断收到超时,所以我不知道从哪里开始。由于重定向,我绝对没有看到对 /home 的请求。所以在它被发送到代理之前,它必须在代码中出错。

我想知道这是否真的是一个错误,或者我做错了什么。只要您可以访问可以发送流量的代理,就很容易复制。请看下面的代码:

import requests

proxiesDict = {
    'http': "http://127.0.0.1:8080",
    'https': "http://127.0.0.1:8080"
}

# This fails with "requests.exceptions.ProxyError: Cannot connect to proxy. Socket error: [Errno 111] Connection refused." when it tries to follow the redirect to /home
r = requests.get("https://www.paypal.com/", proxies=proxiesDict)
# This succeeds.
r = requests.get("https://www.paypal.com/home", proxies=proxiesDict)

直接使用 urllib3 时也会发生这种情况。它可能主要是 urllib3 中的错误,Requests 在后台使用它,但我使用的是更高级别的请求库。见下文:

proxy = urllib3.proxy_from_url('http://127.0.0.1:8080/')

# This fails with the same error as above.
res = proxy.urlopen('GET', https://www.paypal.com/)
# This succeeds
res = proxy.urlopen('GET', https://www.paypal.com/home)

这是使用 Requests 时的回溯:

Traceback (most recent call last):
  File "tests/downloader_tests.py", line 22, in test_proxy_https_request
    r = requests.get("https://www.paypal.com/", proxies=proxiesDict)
  File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 55, in get
    return request('get', url, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 382, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 505, in send
    history = [resp for resp in gen] if allow_redirects else []
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 167, in resolve_redirects
    allow_redirects=False,
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 485, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 375, in send
    raise ProxyError(e)
requests.exceptions.ProxyError: Cannot connect to proxy. Socket error: [Errno 111] Connection refused.

更新:

问题似乎只发生在 302(找到)重定向​​而不是正常的 301 重定向(永久移动)。另外,我注意到使用 Chrome 浏览器时,Paypal 不会返回重定向。使用请求时我确实看到了重定向——即使我为此实验借用了 Chrome 的用户代理。我正在寻找更多返回 302 的 URL,以获取更多数据点。

我需要它适用于所有 URL,或者至少了解我看到这种行为的原因。

【问题讨论】:

  • 失败了,但是回溯是什么?
  • 它是否适用于任何其他网站?
  • @Games 我添加了回溯。
  • @Truerror 你说得对,它适用于大多数其他网站。它适用于usbank.comatt.com/olam。两者都使用 HTTP 代码 301 重定向(永久移动)。但是,我注意到 Paypal 正在返回 302(已找到)。这似乎是不同的。
  • 这里是一个非常相似的问题的修复链接,以及由此产生的讨论,您可能会觉得很有启发性:github.com/kennethreitz/requests/pull/269

标签: python https proxy python-requests urllib3


【解决方案1】:

这是 urllib3 中的一个错误。我们将其跟踪为urllib3 issue #295

【讨论】:

  • 谢谢卢卡萨。关于补丁何时准备就绪的任何想法?有什么我可以做的吗?
  • 不知道,坦率地说。取决于某人何时有时间坐下来,理解并修复它。如果您想尝试自己修复它,欢迎您这样做!
猜你喜欢
  • 2012-08-31
  • 2015-05-14
  • 1970-01-01
  • 2021-03-27
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
相关资源
最近更新 更多