Python 使用 POST 和 urllib2 访问 Web API
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4195325/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using POST and urllib2 to access web API
提问by neomech
I am trying to access a web API using a POST technique. I AM able to access it using a GET technique, but the API owners tell me that certain functionality only works with POST. Unfortunately I can't seem to get POST working.
我正在尝试使用 POST 技术访问 Web API。我可以使用 GET 技术访问它,但 API 所有者告诉我某些功能仅适用于 POST。不幸的是,我似乎无法让 POST 工作。
Here's what works with GET:
以下是 GET 的作用:
API_URL = "http://example.com/api/"
def call_api(method, **kwargs):
url = API_URL + method
if kwargs:
url += '?' + urllib.urlencode(kwargs)
req = urllib2.Request(url)
auth = 'Basic ' + base64.urlsafe_b64encode("%s:%s" % (USER, PASS))
req.add_header('Authorization', auth)
return urllib2.urlopen(req)
Here's what does NOT work with POST (causes HTTP 400 error):
以下是不适用于 POST 的内容(导致 HTTP 400 错误):
API_URL = "http://example.com/api/"
def call_api(method, **kwargs):
url = API_URL + method
data=''
if kwargs:
data=urllib.urlencode(kwargs)
req = urllib2.Request(url, data)
auth = 'Basic ' + base64.urlsafe_b64encode("%s:%s" % (USER, PASS))
req.add_header('Authorization', auth)
return urllib2.urlopen(req)
Does anything jump out at anyone as being inherently incorrect in the POST code? I've never done a POST call before but everything I've read seems to suggest that my code is reasonable. Is there some different way I'm supposed to do the add_header thing for the authorization if I'm using POST?
任何人都会因为 POST 代码中的固有错误而跳出任何东西吗?我以前从未做过 POST 调用,但我读过的所有内容似乎都表明我的代码是合理的。如果我使用 POST,是否有一些不同的方式我应该为授权做 add_header 事情?
采纳答案by sneeu
With urllib2you need to add the data to the POSTbody:
随着urllib2您需要将数据添加到POST身体:
def call_api(method, **kwargs):
url = API_URL + method
req = urllib2.Request(url)
if kwargs:
req.add_data(urllib.urlencode(kwargs))
auth = 'Basic ' + base64.urlsafe_b64encode("%s:%s" % (USER, PASS))
req.add_header('Authorization', auth)
# req.get_method() -> 'POST'
return urllib2.urlopen(req)
回答by bgporter
As @sneeu notes above, it's the act of adding the data to be posted to the request that converts the request from a GET into a POST.
正如上面@sneeu 所指出的,将要发布的数据添加到请求中的行为将请求从 GET 转换为 POST。
However, this still assumes that what the API is expecting to receive in the POST body is form-encoded data. Many more recent APIs that I've worked with are expecting something else in there (XML or JSON, most commonly).
但是,这仍然假设 API 期望在 POST 正文中接收的是表单编码数据。我使用过的许多最近的 API 都在期待其他东西(最常见的是 XML 或 JSON)。
Can you verify what that API is expecting to receive as a data payload?
您能否验证该 API 期望接收的数据负载是什么?
回答by fandyst
I have faced the same problem, I want to send data with the POST method of HTTP, but after dir(req)I found get_method, but no set_method, and I also found there is a property called data, so try this out:
我遇到了同样的问题,我想用HTTP的POST方法发送数据,但是dir(req)我发现之后get_method,却没有set_method,而且我还发现有一个属性叫做data,所以试试这个:
>>> req.data={"todototry":"123456"}
>>> req.get_method()
'POST'
>>>
Thanks @sneeu.
谢谢@sneeu。

