Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

ちょっとした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です。
neko_the_shadow
IT業界の片隅でひっそり生きるシステムエンジニアです(´・ω・`)
https://nekotheshadow.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away