通过代理使用Python Requests模块进行HTTP请求不成功,curl却可以?为什么?

11 投票
2 回答
11464 浏览
提问于 2025-04-17 08:15

我用这个curl命令可以在Bash中得到我想要的响应。

curl -v -u z:secret_key --proxy http://proxy.net:80  \
-H "Content-Type: application/json" https://service.com/data.json

我已经看过关于使用Requests模块的代理的其他帖子了

这个帖子帮我写出了Python代码,但我需要通过代理发送请求。然而,即使我提供了正确的代理,还是不行。也许我只是没注意到什么?

>>> requests.request('GET', 'https://service.com/data.json', \
>>> headers={'Content-Type':'application/json'}, \ 
>>> proxies = {'http' : "http://proxy.net:80",'https':'http://proxy.net:80'}, \
>>> auth=('z', 'secret_key'))

而且,在同一个Python控制台中,我可以用urllib发送请求,并且成功了。

>>> import urllib
>>> urllib.urlopen("http://www.httpbin.org").read()
---results---

即使在一个非https地址上尝试requests也失败了。

>>> requests.get('http://www.httpbin.org')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Python/2.6/site-packages/requests/api.py", line 79, in get
   return request('get', url, **kwargs)
File "/Library/Python/2.6/site-packages/requests/api.py", line 66, in request
    prefetch=prefetch
File "/Library/Python/2.6/site-packages/requests/sessions.py", line 191, in request
    r.send(prefetch=prefetch)
File "/Library/Python/2.6/site-packages/requests/models.py", line 454, in send
    raise ConnectionError(e)
requests.exceptions.ConnectionError: Max retries exceeded for url:

Requests模块非常优雅和强大,但在这种情况下怎么会失败呢?

2 个回答

1

根据上面的回答,我们尝试了human_curl。

但是human_curl出现了很多未知错误,而urllib3则给出了正确的错误信息,比如请求超时、最大重试次数超过等。

所以,我们又回到了urllib3,urllib3是线程安全的。我们对urllib3很满意。

现在唯一的问题是我们遇到了“最大重试次数超过”的错误,我们不知道该怎么解决。

我们猜可能和服务器或代理有关,但不太确定。

9

问题其实出在Python的标准网址访问库上,也就是urllib、urllib2和httplib。我记不清具体是哪个库出了问题,但为了简单起见,我们就叫它urllib吧。不幸的是,urllib没有实现HTTP Connect方法,而这个方法是通过HTTP(S)代理访问HTTPS网站所必需的。我尝试过用urllib来添加这个功能,但没有成功(距离我上次尝试已经有一段时间了)。所以,遗憾的是,我知道的唯一可行的办法就是使用pycurl。

不过,有一个相对干净的解决方案,它的API几乎和Python的requests库一模一样,但它使用的是pycurl作为后端,而不是Python的标准库。

这个库叫做 human_curl。我自己用过,效果很好。

撰写回答