JSONは Web APIなどのデータ交換形式としても広く使われているデータ形式です。Python標準の組込みモジュールであるjsonを使ってJSONデータを扱うことができます。本記事では、
- JSONデータをPythonオブジェクトへ変換し、Python上で操作できるようにする方法
- Pythonオブジェクト(辞書、リスト)からJSONデータ(文字列)に変換する方法
について、具体例を用いてまとめました。
また最後に、実際のWeb APIを使った実用的な使い方も記載しました。
JSONについて
JSONとは?
- “JavaScript Object Notation”の略。javascriptの仕様の一部として作られた軽量なデータ形式
- JavaScript専用のデータ形式ではなく、様々なソフトウェア、プログラミング言語間におけるデータ交換に使えるよう設計されている
- Web APIなどのデータ交換形式としても広く使われている
データフォーマット
JSONは2つの構造を基にしています。(参考:https://www.json.org/json-ja.html)
- 名前:値のペアの集まり
- 名前:文字列のみ。ダブルクォーテーション(“)で囲うこと
{'item': "Book", 'price': 1200} ★シングルクォーテーション(')は不正
また下記の表記は名前が変数に見えてしまいJSONとしては不正なので注意!
{item: "Book", price: 1200} ★変数に見えてしまい不正
{"Item": "Book", "price": 1200}
値を(,)(カンマ)で区切って、[ ](角かっこ)でくくる。
["aaa", {"name":"Takeshi", "age":19}, ["bbb", "ccc"]]
jsonモジュールの使いかた
PythonでJSONデータを扱うには、jsonモジュールが便利です。
但し、JSONはPythonでサポートしている全てのデータ型を使える訳ではありません。使えるデータ型は以下に限定されることに注意です。
尚、このモジュールは標準の組込みライブラリのため新規にインストールする必要はありません。
JSONデータをPythonオブジェクトへ変換する
Web APIなどから出力されるJSONデータは文字列として取得されます。
これをPythonで操作する為には、取得したJSONデータをPythonオブジェクトに変換する必要があります。
JSONデータをPythonオブジェクトへ変換するには、loads()を使います。
例を以下に示します。
# JSONデータ(文字列)
>>> data = '[{"name": "Taro", "age": 14, "check": true}, {"name": "Jiro", "age": 23, "check": false}, {"name": "Tom", "age": 16
, "check": false}]'
# jsonモジュールをimport
>>> import json
# JSONデータをPythonオブジェクトへ変換
>>> j2p_data = json.loads(data)
# 出力結果(Pythonオブジェクト)
>>> j2p_data
[{'name': 'Taro', 'age': 14, 'check': True}, {'name': 'Jiro', 'age': 23, 'check': False}, {'name': 'Tom', 'age': 16, 'check': False}]
# リスト型です。
>>> type(j2p_data)
<class 'list'>
リストと辞書の組み合わせなので、Pythonコードの中で任意のデータを取得することが出来ます。
>>> j2p_data[0]
{'name': 'Taro', 'age': 14, 'check': True}
>>> j2p_data[1]['age']
23
PythonオブジェクトをJSONデータ(文字列)に変換
Pythonオブジェクト(リスト、辞書等)を、JSONデータ(文字列)に変換するには、dumps()メソッドを使います。
使い方の例を以下に示します。
# Pythonオブジェクト(リストと辞書の組み合わせ)
>>> data = [{'name': 'Taro', 'age': 14, 'check': True}, {'name': 'Jiro', 'age': 23, 'check': False}, {'name': 'Tom', 'age': 16, 'check': False}]
# jsonモジュールをimport
>>> import json
# PythonオブジェクトをJSONデータに変換
>>> p2j_data = json.dumps(data)
# JSONデータ(文字列)
>>> p2j_data
'[{"name": "Taro", "age": 14, "check": true}, {"name": "Jiro", "age": 23, "check": false}, {"name": "Tom", "age": 16, "check": false}]'
# 文字列型です。
>>> type(p2j_data)
<class 'str'>
JSONデータを見やすく整形する
上記例のように、dumps()のデフォルト設定では改行やインデントが無く出力結果がとても見にくいです。
そこで、dumps()にindentパラメータを設定すると、print()で表示した時に見やすくなります。
# Pythonオブジェクト(リストと辞書の組み合わせ)
>>> data = [{'name': 'Taro', 'age': 14, 'check': True}, {'name': 'Jiro', 'age': 23, 'check': False}, {'name': 'Tom', 'age': 16, 'check': False}]
# Pythonオブジェクトをインデント付きでJSONデータ(文字列)に変換
>>> p2j_data = json.dumps(data, indent=4)
# print()で見やすくなりました
>>> print(p2j_data)
[
{
"name": "Taro",
"age": 14,
"check": true
},
{
"name": "Jiro",
"age": 23,
"check": false
},
{
"name": "Tom",
"age": 16,
"check": false
}
]
日本語文字が含まれている場合
dumps()では、デフォルトでは日本語のような非ASCII文字はUnicodeエスケープされます。
つまり、例えば日本語文字のりんごは\u308a\u3093\u3054といった表記で出力されます。
具体例で見てみます。
# 日本語が含まれたPythonオブジェクト
>>> data_python = [{'name': 'たろー', 'age': 14, 'check': True}, {'name': '次郎', 'age': 23, 'check': False}, {'name': 'Tom', 'age': 16, 'check': False}]
# dumps()でJSON形式に変換
>>> data_json = json.dumps(data_python, indent=4)
# 日本語の箇所がUnicodeエスケープされている(★部)
>>> print(data_json)
[
{
"name": "\u305f\u308d\u30fc", (★)
"age": 14,
"check": true
},
{
"name": "\u6b21\u90ce", (★)
"age": 23,
"check": false
},
{
"name": "Tom",
"age": 16,
"check": false
}
]
日本語を日本語として表記するには、dumps()の引数ensure_ascii = Falseを設定します。
# ensure_ascii = Falseに設定
>>> data_json = json.dumps(data_python, indent=4, ensure_ascii=False)
>>> print(data_json)
[
{
"name": "たろー",
"age": 14,
"check": true
},
{
"name": "次郎",
"age": 23,
"check": false
},
{
"name": "Tom",
"age": 16,
"check": false
}
]
PythonオブジェクトをJSON形式でファイルへ保存する
dump()メソッドは、PythonオブジェクトをJSON形式でファイルへ保存することが可能です。
書式は下記の通りで、PythonオブジェクトobjをJSON形式のfile-likeオブジェクトfpに格納します。
※第3引数以降は細かいので割愛しています。
json.dump(obj, fp)
具体例を以下に示します。
>>> import json
>>> data_python = [{'name': 'たろー', 'age': 14, 'check': True}, {'name': '次郎', 'age': 23, 'check': False}, {'name': 'Tom', 'age': 16, 'check': False}]
>>> with open('sample.json', 'w') as fp:
... json.dump(data_python, fp, indent=4, ensure_ascii=False)
出力結果を確認します。前項で述べたindentやensure_asciiの設定も反映されていますね。
~$ cat sample.json
[
{
"name": "たろー",
"age": 14,
"check": true
},
{
"name": "次郎",
"age": 23,
"check": false
},
{
"name": "Tom",
"age": 16,
"check": false
}
]
実際にWeb APIにアクセスしてみる
例として、各種気象データの無料APIを提供するオンラインサービスのOpenWeather で現在の天気情報を取得してみます。
※使用するにはアカウント登録が必要ですが、お試しで使うには無料プランでも十分だと思います。
以下は東京都の現在の天気を取得するコード例です。
API Keyは別ファイル(config.py)から呼び出すようにしています。
import json
import requests
import config
# API keyはconfigy.pyから読み出す
API_KEY = config.API_KEY
# 東京のcity ID(http://bulk.openweathermap.org/sample/city.list.json.gz)
city_id = '1850147'
# API endpoint
url = 'https://api.openweathermap.org/data/2.5/weather'
# 言語は日本語、温度の単位は℃に設定
params = {"id": city_id, "appid" : API_KEY, 'lang': 'ja', 'units':'metric'}
res = requests.get(url, params=params)
# JSONフォーマットをPythonオブジェクト(辞書型)に変換
data = json.loads(res.text)
# 辞書データから所望の値を取り出す
location = data['name']
weather = data['weather'][0]['main']
tempreture = data['main']['temp']
humidity = data['main']['humidity']
print(f'現在、{location}の天気は{weather}、気温は{tempreture}℃、湿度は{humidity}%です。')
実行結果は以下です。
$ python web_api_openweather.py
現在、東京都の天気はClouds、気温は21.46℃、湿度は76%です。
確認した環境
- OS:Ubuntu20.04LTS
- Python 3.9.7
まとめ
Pythonの標準ライブラリのjsonモジュールを使ってJSON形式データを扱う方法についてまとめました。
Web APIのレスポンスフォーマットとしてjsonをサポートしていることが多いので是非使いこなしたいです。
コメント
[…] PythonオブジェクトをJsonに変換したい場合はこの記事 […]