使用POST和urllib2访问Web API

时间:2010-11-16 14:43:19

标签: python http post urllib2

我正在尝试使用POST技术访问Web API。我能够使用GET技术访问它,但API所有者告诉我某些功能仅适用于POST。不幸的是我似乎无法让POST工作。

这适用于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)

这是什么不适用于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)

任何人都会因为POST代码本身不正确而跳出来吗?我之前从未做过POST调用,但我读过的所有内容似乎都表明我的代码是合理的。如果我使用POST,是否有一些不同的方式我应该为授权执行add_header操作?

3 个答案:

答案 0 :(得分:10)

使用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)

答案 1 :(得分:2)

正如@sneeu上面所说,这是将要发布的数据添加到将请求从GET转换为POST的请求的行为。

但是,这仍然假设API期望在POST正文中接收的是表单编码数据。我使用过的许多最新API都期待其他东西(XML或JSON,最常见)。

您能否验证该API期望作为数据有效负载接收什么?

答案 2 :(得分:1)

我遇到了同样的问题,我想用HTTP的POST方法发送数据,但在dir(req)之后我发现了get_method,但没有set_method,我也发现了是一个名为data的属性,所以试试这个:

>>> req.data={"todototry":"123456"}
>>> req.get_method()
'POST'
>>>

谢谢@sneeu。