ちょっとしたPython3スクリプトでjsonをPOSTしたいということがよくあると思います(適当)。
まずはサンプルコード。
import urllib.request, json
if __name__ == '__main__':
url = "http://xxxx/xxxx"
method = "POST"
headers = {"Content-Type" : "application/json"}
# PythonオブジェクトをJSONに変換する
obj = {"xxx" : "xxxx", 123 : 123}
json_data = json.dumps(obj).encode("utf-8")
# httpリクエストを準備してPOST
request = urllib.request.Request(url, data=json_data, method=method, headers=headers)
with urllib.request.urlopen(request) as response:
response_body = response.read().decode("utf-8")
次に簡単な実例として「ニコニコ動画 『スナップショット検索API』」を利用して、「結月ゆかり」の検索結果のうち、再生数が多い30個の動画を取得してみたいと思います。
import urllib.request, json
if __name__ == '__main__':
url = "http://api.search.nicovideo.jp/api/snapshot/"
method = "POST"
obj = {
"query" : "結月ゆかり",
"service" : ["video"],
"search" : ["title", "description", "tags"],
"join" : ["title", "view_counter"],
"sort_by" : "view_counter",
"order" : "desc",
"size" : 30,
"issuer" : "xxxxxxxxxxxxxxxxxxxxx"
}
json_data = json.dumps(obj).encode("utf-8")
headers = {"Content-Type" : "application/json"}
request = urllib.request.Request(url, data=json_data, headers=headers, method=method)
with urllib.request.urlopen(request) as response:
response_body = response.read().decode("utf-8")
result_objs = json.loads(response_body.split('\n')[0])
for result_obj in result_objs["values"]:
print("{0:<10}{1}".format(result_obj["view_counter"], result_obj["title"]))
# 2903887 【初音ミク】こちら、幸福安心委員会です。【オリジナル】
# 2331059 みwなwぎwっwてwきwたwww(篠笛禁断症状L5)
# 1979283 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ#1
# 1896978 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ#5
# 1805589 【Minecraft】ゆかり「メイジタワー爆破しましょう」part1【VOICEROID+実況】
# 1662622 【結月ゆかり】名前のない怪物を歌ってもらった【PSYCHO-PASS】
# 1617931 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ#3
# 1587257 【初音ミク】永遠に幸せになる方法、見つけました。【オリジナル】
# 1531263 【結月ゆかり】幸せになれる隠しコマンドがあるらしい【オリジナル】
# 1499237 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ#2
# 1424024 【結月ゆかりの】チュルリラ・チュルリラ・ダッダッダ!
# 1391173 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ#7
# 1356847 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ#6
# 1354592 【Minecraft】ゆかり「メイジタワー爆破しましょう」part3【VOICEROID+実況】
# 1261669 【Minecraft】ゆかり「メイジタワー爆破しましょう」part2【VOICEROID+実況】
# 1241053 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ#8
# 1223469 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ#4
# 1201715 【Minecraft】ゆかり「メイジタワー爆破しましょう」part4【VOICEROID+実況】
# 1182955 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ#9
# 1177519 【Minecraft】ゆかり「メイジタワー爆破しましょう」part9【VOICEROID+実況】
# 1069852 【MAYU】一途な片思い、実らせたい小さな幸せ。【オリジナル】
# 1045793 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ⑩
# 1040149 【Minecraft】ゆかり「メイジタワー爆破しましょう」part5【VOICEROID+実況】
# 1008825 【Minecraft】ゆかり「メイジタワー爆破しましょう」part6【VOICEROID+実況】
# 993675 【結月ゆかりの】サヨナラチェーンソー
# 963262 【Minecraft】ゆかり「メイジタワー爆破しましょう」part7【VOICEROID+実況】
# 927444 【Minecraft】ゆかり「メイジタワー爆破しましょう」part8【VOICEROID+実況】
# 895328 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ⑫
# 892567 【Minecraft】ゆかり「メイジタワー爆破しましょう」最終回【VOICEROID+実況】
# 878046 【Minecraft】ゲリラクラフト 周囲に防衛線を築き地雷を張り巡らせるんだ⑪
いくつか注意点があるので、それも簡単に紹介しておきますね。
- POSTするデータ、つまり
urllib.request.Request()
のdata
に指定する引数はbytes
型である必要があります。要するにstr
ではだめで、encode()
|などを使って変換してやる必要があります。- レスポンスの結果を取得する
http.client.HTTPResponse#read()
の戻り値もbytes
型なので、str
に変換する場合はdecode()
などを利用します。
- レスポンスの結果を取得する
-
json.dupms()
はPythonオブジェクトをjson文字列(str
)に変換してくれます。json.dump()
という似たような名前のメソッドもありますが、これは別物です。- 同様に
json.loads()
とjson.load()
も別物です。
- 同様に
-
urllib.request.urlopen()
の戻り値はhttp.client.HTTPResponse
です。