LoginSignup
94
88

More than 5 years have passed since last update.

Python3のスクリプトでjsonをPOSTする

Posted at

ちょっとした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です。
94
88
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
94
88