結果だけでなく過程も見てください

日々の奮闘を綴る日記です。

Pythonでjsonを扱うときの備忘録

超基本ですが、最近始めたばかりで覚えられないので。

インポートするパッケージ

スクリプトで以下をimportしてください。

import json
import os

今回扱うjsonのデータ

{
    "kind":"cat",
    "name":"nina",
    "age":10,
    "id":"abc",
    "items":[
        {
            "kind":"color",
            "rarity":"common",
            "id":"silver"
        },
        {
            "kind":"texture",
            "rarity":"epic",
            "color":"gold"
        },
        {
            "kind":"claw",
            "rarity":"legendary",
            "name":"dragon claw"
        },
        {
            "numbers":[20,40,50,99],
            "strs":["z","y","x","w"],
            "arrays":[[1,2,3],["a","b","c"]]
        }
    ]
}

こいつを文字列として使いたい場合は、秀丸などにコピペして以下を行ってください。

  • 気になる人は正規表現「^ *」を空文字列に置換する(やらなくてもよい)
  • 改行コード正規表現「[\r\n]」を空文字列に置換する
  • 文字「"」を「\"」に置換する
ちなみにPythonで複数のコメントアウトをする場合は以下のように"""で囲います。
"""
この部分はコメントになる
"""

文字列をjsonとして認識する

json.loadsメソッドを使います。第一引数にjsonの文字列を渡します。

json_str = "{\"kind\":\"cat\",\"name\":\"nina\",\"age\":10,\"id\":\"abc\",\"items\":[{\"kind\":\"color\",\"rarity\":\"common\",\"id\":\"silver\"},{\"kind\":\"texture\",\"rarity\":\"epic\",\"color\":\"gold\"},{\"kind\":\"claw\",\"rarity\":\"legendary\",\"name\":\"dragon claw\"},{\"numbers\":[20,40,50,99],\"strs\":[\"z\",\"y\",\"x\",\"w\"],\"arrays\":[[1,2,3],[\"a\",\"b\",\"c\"]]}]}"
json_data = json.loads(json_str)
print("json_str type is " + str(type(json_str)))
print("json_data type is " + str(type(json_data)))

json_dataがjsonのデータとなります。
型情報の出力は以下のようになるはずです。

json_str type is <class 'str'>
json_data type is <class 'dict'>

ファイルから読み込んだ内容をjsonとして認識する

json.loadメソッドを使います。第一引数にjsonが書かれたファイルのファイルディスクリプタを渡します。

with open( os.path.join(os.getcwd(),'sample.json') ) as f:
    json_data = json.load(f)
    print("json_data type is " + str(type(json_data)))

jsonデータを文字列化する

json.dumpsメソッドを使います。第一引数にjsonの文字列を渡します。

json_str = "{\"kind\":\"cat\",\"name\":\"nina\",\"age\":10,\"id\":\"abc\",\"items\":[{\"kind\":\"color\",\"rarity\":\"common\",\"id\":\"silver\"},{\"kind\":\"texture\",\"rarity\":\"epic\",\"color\":\"gold\"},{\"kind\":\"claw\",\"rarity\":\"legendary\",\"name\":\"dragon claw\"},{\"numbers\":[20,40,50,99],\"strs\":[\"z\",\"y\",\"x\",\"w\"],\"arrays\":[[1,2,3],[\"a\",\"b\",\"c\"]]}]}"
json_data = json.loads(json_str)
print(json.dumps(json_data))

jsonデータをファイル出力する

json.dumpメソッドを使います。第一引数にjsonのデータを、第二引数に出力するファイルのファイルディスクリプタを、第三引数以降にオプションを指定します。今回はインデントを4に指定しています。
json_str = "{\"kind\":\"cat\",\"name\":\"nina\",\"age\":10,\"id\":\"abc\",\"items\":[{\"kind\":\"color\",\"rarity\":\"common\",\"id\":\"silver\"},{\"kind\":\"texture\",\"rarity\":\"epic\",\"color\":\"gold\"},{\"kind\":\"claw\",\"rarity\":\"legendary\",\"name\":\"dragon claw\"},{\"numbers\":[20,40,50,99],\"strs\":[\"z\",\"y\",\"x\",\"w\"],\"arrays\":[[1,2,3],[\"a\",\"b\",\"c\"]]}]}"
json_data = json.loads(json_str)

with open( os.path.join(os.getcwd(),'sample_out.json'), 'w' ) as f:
    json.dump(json_data, f, indent=4)

jsonデータへのアクセス

[]で順に追っていくだけで目的のデータにアクセス可能です。

json_str = "{\"kind\":\"cat\",\"name\":\"nina\",\"age\":10,\"id\":\"abc\",\"items\":[{\"kind\":\"color\",\"rarity\":\"common\",\"id\":\"silver\"},{\"kind\":\"texture\",\"rarity\":\"epic\",\"color\":\"gold\"},{\"kind\":\"claw\",\"rarity\":\"legendary\",\"name\":\"dragon claw\"},{\"numbers\":[20,40,50,99],\"strs\":[\"z\",\"y\",\"x\",\"w\"],\"arrays\":[[1,2,3],[\"a\",\"b\",\"c\"]]}]}"
    json_data = json.loads(json_str)
print(json_data["kind"])
print(json_data["name"])
print(json_data["age"])
print(json_data["id"])
print(json_data["items"][0]["kind"])
print(json_data["items"][1]["kind"])
print(json_data["items"][2]["kind"])
print(json_data["items"][3]["numbers"][1])
print(json_data["items"][3]["arrays"][1][2])

結果は以下。

cat
nina
10
abc
color
texture
claw
40
c

また[]が長くなりすぎる場合など、途中の配列オブジェクトを取得してそこから辿ることも可能です。

json_str = "{\"kind\":\"cat\",\"name\":\"nina\",\"age\":10,\"id\":\"abc\",\"items\":[{\"kind\":\"color\",\"rarity\":\"common\",\"id\":\"silver\"},{\"kind\":\"texture\",\"rarity\":\"epic\",\"color\":\"gold\"},{\"kind\":\"claw\",\"rarity\":\"legendary\",\"name\":\"dragon claw\"},{\"numbers\":[20,40,50,99],\"strs\":[\"z\",\"y\",\"x\",\"w\"],\"arrays\":[[1,2,3],[\"a\",\"b\",\"c\"]]}]}"
    json_data = json.loads(json_str)
items_array = json_data.get("items", [])
print(items_array[1]["rarity"])
items_array_of_array = items_array[3]["arrays"][0]
print(items_array_of_array[0])

結果は以下のようになる。

epic
1

実用例

youtubeオブジェクトを作成するためのdeveloperKeyについては、Youtube Developerへの登録が必要です。
以下の記事を参考に登録・APIキーの取得を行ってください。
Youtube APIで生放送のアーカイブの全コメントを拾ったり、スパチャ額の合計を取得する方法 - 結果だけでなく過程も見てください

※注意事項※

youtubeのsearchには一日に取得できる上限があるため、途中でテストできなくなる可能性があります。
やたらと無駄にクエリーを投げないようにしましょう!
Youtube(2020/10/31現在)のチャンネルIDからビデオID一覧を含むjsonデータをファイル出力する
from apiclient.discovery import build
import json
import os
from bs4 import BeautifulSoup
import ast
import requests
import requests_html
import re
import sys
import glob
from retry import retry

def get_api_auth_youtube():
    youtube = build('youtube', 'v3', developerKey='<ここについては↑で言った通り別記事を参考にしてください')
    return (youtube)

@retry(EOFError, tries=5, delay=10)
def get_video_id_list(youtube, channel_id):
    curToken = None

    search_response = youtube.search().list(
        part = "id,snippet",
        channelId = channel_id,
        maxResults = 2,  # クエリー投げすぎ防止のため2件としておきます
        order = "date",  # 日付順にソートします
        pageToken = curToken
    ).execute()

    with open( os.path.join(os.getcwd(),'sample_out2.json'), 'w' ) as f:
        json.dump(search_response, f, indent=4)

if __name__ == '__main__':
    youtube = get_api_auth_youtube()
    get_video_id_list(youtube, '<お好きなチャンネルID>')
チャンネルIDは特定のチャンネルのURLの末尾にある文字列のことを指します。

今後やりたいこと

  • 日本語などの文字コードの整理
  • ファイル入力・出力などのオプション整理
プライバシーポリシー お問い合わせ