使用Python3的脚本进行JSON的POST请求
经常有人想用一个简单的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")
我想要使用”Niconico视频 ‘Snapshot搜索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です。