使用urllib2进行POST调用而不是GET

时间:2011-06-14 18:50:11

标签: python urllib2 urllib

在urllib2和POST调用上有很多东西,但是我遇到了问题。

我正在尝试对服务进行简单的POST调用:

url = 'http://myserver/post_service'
data = urllib.urlencode({'name' : 'joe',
                         'age'  : '10'})
content = urllib2.urlopen(url=url, data=data).read()
print content

我可以看到服务器日志,当我发送数据时,它说我正在进行GET调用 urlopen的论据。

该库引发了404错误(未找到),这对于GET调用是正确的,POST调用处理得很好(我也尝试在HTML表单中使用POST)。

7 个答案:

答案 0 :(得分:45)

之前可能已经回答过:Python URLLib / URLLib2 POST

您的服务器可能正在执行从http://myserver/post_servicehttp://myserver/post_service/的302重定向。执行302重定向时,请求从POST更改为GET(请参阅Issue 1401)。尝试将url更改为http://myserver/post_service/

答案 1 :(得分:41)

分阶段进行,并修改对象,如下所示:

# make a string with the request type in it:
method = "POST"
# create a handler. you can specify different handlers here (file uploads etc)
# but we go for the default
handler = urllib2.HTTPHandler()
# create an openerdirector instance
opener = urllib2.build_opener(handler)
# build a request
data = urllib.urlencode(dictionary_of_POST_fields_or_None)
request = urllib2.Request(url, data=data)
# add any other information you want
request.add_header("Content-Type",'application/json')
# overload the get method function with a small anonymous function...
request.get_method = lambda: method
# try it; don't forget to catch the result
try:
    connection = opener.open(request)
except urllib2.HTTPError,e:
    connection = e

# check. Substitute with appropriate HTTP code.
if connection.code == 200:
    data = connection.read()
else:
    # handle the error case. connection.read() will still contain data
    # if any was returned, but it probably won't be of any use

通过这种方式,您可以扩展为制作PUTDELETEHEADOPTIONS请求,只需替换方法的值,甚至将其包含在一个功能。根据您要执行的操作,您可能还需要一个不同的HTTP处理程序,例如用于多文件上传。

答案 2 :(得分:13)

requests模块可能会减轻您的痛苦。

url = 'http://myserver/post_service'
data = dict(name='joe', age='10')

r = requests.post(url, data=data, allow_redirects=True)
print r.content

答案 3 :(得分:10)

阅读urllib Missing Manual。从那里拉出以下简单的POST请求示例。

url = 'http://myserver/post_service'
data = urllib.urlencode({'name' : 'joe', 'age'  : '10'})
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
print response.read()

根据@Michael Kent的建议,请考虑requests,这很棒。

编辑:这就是说,我不知道为什么将数据传递给urlopen()不会导致POST请求;这应该。我怀疑你的服务器正在重定向或行为不端。

答案 4 :(得分:5)

如果您提供数据参数(就像您正在做的那样)发送POST:

来自文档: “当提供数据参数时,HTTP请求将是POST而不是GET”

所以..添加一些调试输出以查看客户端的内容。

您可以将代码修改为此,然后重试:

import urllib
import urllib2

url = 'http://myserver/post_service'
opener = urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1))
data = urllib.urlencode({'name' : 'joe',
                         'age'  : '10'})
content = opener.open(url, data=data).read()

答案 5 :(得分:1)

请改为尝试:

url = 'http://myserver/post_service'
data = urllib.urlencode({'name' : 'joe',
                         'age'  : '10'})
req = urllib2.Request(url=url,data=data)
content = urllib2.urlopen(req).read()
print content

答案 6 :(得分:-3)

url="https://myserver/post_service"
data["name"] = "joe"
data["age"] = "20"
data_encoded = urllib2.urlencode(data)
print urllib2.urlopen(url + "?" + data_encoded).read()

可能这可以帮助