web-dev-qa-db-ja.com

urllib2を使用してGETの代わりにPOST呼び出しを行う

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

サーバーのログを見ることができ、urlopenにデータ引数を送信しているときに、GET呼び出しを実行していると表示されます。

ライブラリはGET呼び出しに適切な404エラー(見つからない)を発生させます。POST呼び出しは適切に処理されます(HTMLフォーム内でPOST )。

53
alfonso.kim

これは以前に回答された可能性があります: Python URLLib/URLLib2 POST

サーバーは、おそらくhttp://myserver/post_serviceからhttp://myserver/post_service/への302リダイレクトを実行しています。 302リダイレクトが実行されると、要求はPOSTからGETに変わります( Issue 1401 を参照)。 urlhttp://myserver/post_service/に変更してみてください。

43
Gregg

段階的に実行し、次のようにオブジェクトを変更します。

# 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

この方法により、メソッドの値を置き換えるか、関数でラップするだけで、PUTDELETEHEAD、およびOPTIONSのリクエストを作成することもできます。しようとしていることに応じて、異なるHTTPハンドラーも必要になる場合があります。マルチファイルアップロード用。

43
user257111

requests モジュールはあなたの痛みを和らげるでしょう。

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

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

rllib 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 を検討してください。

EDIT:これは、データをurlopen()に渡しても_ ​​POSTリクエストにならない理由はわかりません。そうすべき。サーバーがリダイレクトしている、または動作に問題があると思われます。

10
Rob Cowie

it shouldデータパラメーターを提供する場合(実行しているように)POSTを送信します。

ドキュメントから:「HTTPパラメーターは、データパラメーターが指定されている場合、GETではなくPOSTになります」

そのため、デバッグ出力をいくつか追加して、クライアント側から何が起きているかを確認します。

コードをこれに変更して再試行できます。

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
Corey Goldberg

代わりにこれを試してください:

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
1
rupello