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

在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错误(未find),这是GET调用是正确的,POST调用处理得很好(我也尝试在HTML表单中的POST)。

任何线索都会被折服

这可能已经被回答了: Python URLLib / URLLib2 POST 。

您的服务器可能会执行从http://myserver/post_servicehttp://myserver/post_service/的302redirect。 执行302redirect时,请求从POST更改为GET(请参阅问题1401 )。 尝试将url更改为http://myserver/post_service/

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

 # 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请求,只需要replace方法的值,甚至包含在一个函数中。 根据你想要做什么,你可能还需要一个不同的HTTP处理程序,例如用于多file upload。

请求模块可以缓解你的痛苦。

 url = 'http://myserver/post_service' data = dict(name='joe', age='10') r = requests.post(url, data=data, allow_redirects=True) print r.content 

阅读urllib缺失手册 。 从这里拉出以下简单的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() 

正如@迈克尔·肯特所build议的那样,考虑要求 ,这很好。

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

应该是发送一个POST,如果你提供一个数据参数(就像你在做):

从文档:“提供数据参数时,HTTP请求将是一个POST而不是一个GET”

所以..添加一些debugging输出,看看客户端有什么。

你可以修改你的代码并重试:

 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() 

试试这个:

 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 
 url="https://myserver/post_service" data["name"] = "joe" data["age"] = "20" data_encoded = urllib2.urlencode(data) print urllib2.urlopen(url + "?" + data_encoded).read() 

可能是这可以帮助