REST API を利用する際、レスポンスは JSON 形式であることが多いのではないでしょうか ?
API から返された JSON 形式のデータを Python のオブジェクトに詰め直して処理したり、逆に Python 上での処理結果を JSON 形式に変換して API にするケースについて解説します。
本記事では、JSON の基本的な概念から、Python での具体的な処理方法、実践的なユースケース、さらには日本語対応やカスタムクラスの変換まで、幅広く解説していきます。
1. JSON の基本
JSON は JavaScript Object Notation の略で、データを表現するための形式です。
以下のような特徴があります:
- 軽量なテキスト形式
- プログラミング言語に依存しない
- データ型として、文字列、数値、真偽値、null、配列、オブジェクトをサポート
Python で JSON を扱うための準備
Python には標準ライブラリとしてjson
モジュールが用意されています。
import json
これだけで JSON 処理に必要な機能が使えるようになります。
※ これ以降のサンプルコードは、こちらの import json
を省略して記載します
JSON 文字列から Python オブジェクトへの変換
基本的な使い方
json.loads()
を使用することで変換できます。
# JSON文字列
json_str = '''
{
"name": "pokapu",
"age": 37,
"is_married": true,
"hobbies": ["play guitar", "programming"]
}
'''
# JSON文字列をPythonオブジェクトに変換
data = json.loads(json_str)
# Python の Dict として処理
print(data["name"]) # pokapu
print(data["hobbies"][0]) # play guitar
上記で記載した json_str
の場合、json.loads()
の結果は Dict
になります。
下記のように変換対象の JSON 文字列のトップレベル要素が配列であれば、json.loads()
の結果は List[dict]
になります。
# JSON文字列
json_str = '''
[
{
"name": "apple",
"color": "red"
},
{
"name": "orange",
"color": "orange"
},
{
"name": "banana",
"color": "yellow"
}
]
'''
# JSON文字列をPythonオブジェクトに変換
data = json.loads(json_str)
# Python の Dict の List として処理
print(data[0]["name"]) # apple
print(data[0]["color"]) # red
実践的なユースケース:API レスポンスの処理
他の記事 で紹介した Requests ライブラリを使用すると、API レスポンスの JSON をスムーズに Python 上で処理できます。
import requests
# API からデータを取得する例
response = requests.get("https://api.example.com/users/1")
user_data = response.json() # requests ライブラリは自動的に JSON をパースします
# データの処理
name = user_data["name"]
email = user_data["email"]
Python オブジェクトから JSON への変換
基本的な使い方
Python 上で定義した Dict
(や List[Dict]
) のデータは、json.dumps()
を使用して簡単に JSON 文字列に変換できます。
# Pythonのデータ
user = {
"name": "pokapu",
"age": 37,
"preferences": {
"color": "青",
"food": ["チョコ", "かつ丼"]
}
}
# JSON文字列に変換
json_str = json.dumps(user, ensure_ascii=False, indent=2)
print(json_str)
↓ 出力結果
{
"name": "pokapu",
"age": 37,
"preferences": {
"color": "青",
"food": ["チョコ", "かつ丼"]
}
}
日本語の扱い
先ほどの例のように ensure_ascii=False
を指定することで、日本語のような非 ASCII 文字を直接 JSON に出力できます。
指定しない場合、非 ASCII 文字は \uXXXX
形式でエスケープされます。
# Pythonのデータ
user = {
"name": "pokapu",
"age": 37,
"preferences": {
"color": "青",
"food": ["チョコ", "かつ丼"]
}
}
# JSON文字列に変換
json_str = json.dumps(user, indent=2)
print(json_str)
↓ 出力結果
{
"name": "pokapu",
"age": 37,
"preferences": {
"color": "\u9752",
"food": ["\u30c1\u30e7\u30b3", "\u304b\u3064\u4e3c"]
}
}
カスタムクラスの変換
json.JSONEncoder
を継承したエンコーダーを使用することで、Python 上のオブジェクトの変換ルールをカスタマイズできます。
例えば日付データを ISO フォーマット(ISO 8601)の文字列で json に含めたい場合は、下記のような記述で実現できます。
from datetime import datetime
class User:
def __init__(self, name, created_at):
self.name = name
self.created_at = created_at
def to_dict(self):
return {
"name": self.name,
"created_at": self.created_at.isoformat()
}
# カスタムJSONエンコーダー
class UserJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, User):
return obj.to_dict()
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
# 使用例
user = User("pokapu", datetime.now())
json_str = json.dumps(user, cls=UserJSONEncoder, indent=2)
print(json_str)
↓ 出力結果
{
"name": "pokapu",
"created_at": "2024-11-21T05:59:21.919900"
}
エラーハンドリング
json.loads()
に間違った形式の文字列を渡すと、json.JSONDecodeError
が発生します。
try:
# 不正なJSON文字列
invalid_json = '{"name": "pokapu", age: 37}'
data = json.loads(invalid_json)
except json.JSONDecodeError as e:
print(f"JSONのパースに失敗しました: {e}")
↓ 出力結果
JSONのパースに失敗しました: Expecting property name enclosed in double quotes: line 1 column 20 (char 19)
出力結果を見ると分かるように、文字列のどの位置に問題があるかを例外オブジェクトに含めてくれるので、こちらを参考に修正が実施できますね。
まとめ
Python ではjson
モジュールを使用することで、簡単に JSON データを扱うことができます。
API との連携や設定ファイルの読み書きなど、様々な場面で活用できる重要な機能です。
基本的な使い方を押さえた上で、必要に応じて日本語対応やカスタムエンコーディングなどの応用的な処理を組み合わせることで、より柔軟な JSON 処理が実現できます。