我正在尝试从http://erdos.sdslabs.co/users/shagun.json获取JSON响应。使用浏览器/ Python的Requests库导致身份验证错误,但curl似乎工作正常。
curl http://erdos.sdslabs.co/users/shagun.json
返回JSON响应。
为什么curl请求在普通浏览器或基于请求的请求失败时有效?
答案 0 :(得分:11)
使用telnet检查:
$ telnet erdos.sdslabs.co 80
Trying 62.141.37.215...
Connected to erdos.sdslabs.co.
Escape character is '^]'.
GET http://erdos.sdslabs.co/users/shagun.json HTTP/1.0
HTTP/1.1 302 Found
Date: Sat, 26 Jul 2014 11:18:58 GMT
Server: Apache
Set-Cookie: PHPSESSID=juvg7vrg3vs4t00om3a95m4sc7; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Location: /login
Access-Control-Allow-Origin: http://erdos.sdslabs.co
X-Powered-By: PleskLin
Content-Length: 1449
Connection: close
Content-Type: application/json
{"email":"sshagun.sodhani@gmail.com","username":"shagun","name":"Shagun
[...]
我们看到Web服务器正在响应302 - 重定向到Location / login。请求和Web浏览器都遵循这一点,并达到登录提示。但是,我们看到Web服务器也使用您之后的json进行响应,并且curl(和telnet)非常简单,只能接受该数据。
最佳做法是修复Web服务器,使其不要求您登录,或者在要求用户登录的同时不提供受密码保护的数据。
如果您无法更改网络服务器,您可以告诉请求模块忽略重定向:
import requests
result = requests.get('http://erdos.sdslabs.co/users/shagun.json', allow_redirects=False)
print result.content
答案 1 :(得分:3)
如果您的环境中配置了代理,请在会话/请求中定义代理。
例如,使用会话:
my_proxies = {
'http': 'http://myproxy:8080',
'https': 'https://myproxy:8080'
}
session = requests.Session()
request = requests.Request('POST', 'http://my.domain.com', data=params_template, headers=req_headers, proxies=my_proxies)
prepped = session.prepare_request(request)
response = session.send(prepped)
见文件:
请求http://docs.python-requests.org/en/master/user/quickstart/
会话http://docs.python-requests.org/en/master/user/advanced/
答案 2 :(得分:0)
对于像我这样的晚期Google员工:
就我而言,问题是我使用requests.get(url, data={...})
提供了URL参数。将其更改为requests.get(url, params={...})
后,问题已解决。