PythonでJSON整形する方法

Pythonを使ってJSONデータを簡単に整形・フォーマットする方法と実用的なコード例をご紹介します

PythonでJSONを整形する4つの方法

1. json.dumpsを使用する方法

Pythonの標準ライブラリ「json」モジュールを使って整形できます:

import json

# 整形前のJSONデータ
data = {"name":"太郎","age":30,"skills":["Python","JSON","API"]}

# インデント4でJSON整形
formatted_json = json.dumps(data, indent=4, ensure_ascii=False)
print(formatted_json)
出力結果:
{
    "name": "太郎",
    "age": 30,
    "skills": [
        "Python",
        "JSON",
        "API"
    ]
}

2. json.toolモジュールを使用する方法

コマンドラインから直接JSONファイルを整形できます:

python -m json.tool input.json > output.json

または、Pythonスクリプト内で使用する場合:

import json
import sys

# ファイルからJSONを読み込み整形
with open('input.json', 'r', encoding='utf-8') as f:
    data = json.load(f)

# 整形してファイルに書き込み
with open('output.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, indent=4, ensure_ascii=False)

3. pprintモジュールを使用する方法

複雑なデータ構造を見やすく表示するのに便利です:

import json
from pprint import pprint

# JSONデータ
json_str = '{"name":"太郎","address":{"city":"東京","zip":"100-0001"},"active":true}'

# JSONをPythonオブジェクトに変換
data = json.loads(json_str)

# pprintで整形表示
pprint(data, width=40)
出力結果:
{'active': True,
 'address': {'city': '東京',
             'zip': '100-0001'},
 'name': '太郎'}

4. サードパーティライブラリを使用する方法

より高度な整形機能を利用するには、「jq-python」などのライブラリが便利です:

# pipでインストール: pip install jq
import jq

json_data = '{"users":[{"name":"太郎","active":true},{"name":"花子","active":false}]}'

# jqフィルタを使用して整形
result = jq.compile('.users[] | select(.active==true)').input(text=json_data)
print(result)
出力結果:
{"name":"太郎","active":true}

Pythonではensure_ascii=Falseを指定することで、日本語などの非ASCII文字を正しく処理できます。

JSON整形のカスタマイズ

json.dumpsのオプションを使って整形をカスタマイズできます:

json.dumps(data, 
    indent=2,             # インデントサイズ
    ensure_ascii=False,   # 日本語対応
    sort_keys=True,       # キーをソート
    separators=(',', ': ')  # 区切り文字
)

これらのオプションを組み合わせることで、出力形式を細かく制御できます。

大きなJSONファイルの処理

大容量JSONファイルを効率的に処理する方法:

import json
import ijson  # pip install ijson

# 大きなJSONファイルを少しずつ読み込む
with open('large_file.json', 'rb') as f:
    # 特定のパスの要素だけを抽出
    objects = ijson.items(f, 'items.item')
    
    # 各要素を処理して整形
    for obj in objects:
        formatted = json.dumps(
            obj, indent=2, ensure_ascii=False
        )
        print(formatted)
        # 処理を続ける...

実用的なPython JSON整形スクリプト

1. JSONファイルを整形して保存するスクリプト

#!/usr/bin/env python3
import json
import argparse
import sys

def format_json_file(input_file, output_file, indent=4, sort_keys=False):
    try:
        # JSONファイルを読み込み
        with open(input_file, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        # 整形して書き込み
        with open(output_file, 'w', encoding='utf-8') as f:
            json.dump(data, f, indent=indent, 
                     ensure_ascii=False, sort_keys=sort_keys)
        
        print(f"JSONを整形して {output_file} に保存しました")
        return True
    except json.JSONDecodeError as e:
        print(f"JSONエラー: {e}")
        return False
    except Exception as e:
        print(f"エラー: {e}")
        return False

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='JSONファイルを整形するツール')
    parser.add_argument('input', help='入力JSONファイル')
    parser.add_argument('-o', '--output', help='出力ファイル名')
    parser.add_argument('-i', '--indent', type=int, default=4, help='インデントサイズ')
    parser.add_argument('-s', '--sort', action='store_true', help='キーをソート')
    
    args = parser.parse_args()
    output = args.output or args.input.replace('.json', '_formatted.json')
    
    success = format_json_file(args.input, output, args.indent, args.sort)
    sys.exit(0 if success else 1)

使用方法: python format_json.py input.json -o output.json -i 2 -s

2. JSON整形と検証を行うGUIツール

import json
import tkinter as tk
from tkinter import scrolledtext, messagebox, filedialog

class JSONFormatterApp:
    def __init__(self, root):
        self.root = root
        root.title("Python JSON整形ツール")
        root.geometry("800x600")
        
        # 入力エリア
        tk.Label(root, text="JSONを入力:").pack(anchor="w", padx=10, pady=(10, 0))
        self.input_text = scrolledtext.ScrolledText(root, height=10)
        self.input_text.pack(fill="both", expand=True, padx=10, pady=5)
        
        # ボタンフレーム
        btn_frame = tk.Frame(root)
        btn_frame.pack(fill="x", padx=10, pady=5)
        
        tk.Button(btn_frame, text="整形", command=self.format_json).pack(side="left", padx=5)
        tk.Button(btn_frame, text="検証", command=self.validate_json).pack(side="left", padx=5)
        tk.Button(btn_frame, text="ファイルを開く", command=self.open_file).pack(side="left", padx=5)
        tk.Button(btn_frame, text="保存", command=self.save_file).pack(side="left", padx=5)
        
        # インデントオプション
        indent_frame = tk.Frame(btn_frame)
        indent_frame.pack(side="right")
        tk.Label(indent_frame, text="インデント:").pack(side="left")
        self.indent_var = tk.IntVar(value=4)
        tk.Spinbox(indent_frame, from_=0, to=8, width=3, textvariable=self.indent_var).pack(side="left")
        
        # 出力エリア
        tk.Label(root, text="結果:").pack(anchor="w", padx=10, pady=(10, 0))
        self.output_text = scrolledtext.ScrolledText(root, height=10)
        self.output_text.pack(fill="both", expand=True, padx=10, pady=5)
    
    def format_json(self):
        try:
            json_str = self.input_text.get("1.0", "end-1c")
            data = json.loads(json_str)
            formatted = json.dumps(data, indent=self.indent_var.get(), ensure_ascii=False)
            self.output_text.delete("1.0", "end")
            self.output_text.insert("1.0", formatted)
        except Exception as e:
            messagebox.showerror("エラー", str(e))
    
    def validate_json(self):
        try:
            json_str = self.input_text.get("1.0", "end-1c")
            json.loads(json_str)
            messagebox.showinfo("検証結果", "有効なJSONです")
        except Exception as e:
            messagebox.showerror("検証エラー", str(e))
    
    def open_file(self):
        file_path = filedialog.askopenfilename(filetypes=[("JSONファイル", "*.json"), ("すべてのファイル", "*.*")])
        if file_path:
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    self.input_text.delete("1.0", "end")
                    self.input_text.insert("1.0", f.read())
            except Exception as e:
                messag
				messagebox.showerror("ファイルエラー", str(e))
    
    def save_file(self):
        file_path = filedialog.asksaveasfilename(
            defaultextension=".json",
            filetypes=[("JSONファイル", "*.json"), ("すべてのファイル", "*.*")]
        )
        if file_path:
            try:
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(self.output_text.get("1.0", "end-1c"))
                messagebox.showinfo("保存完了", f"ファイルを保存しました: {file_path}")
            except Exception as e:
                messagebox.showerror("保存エラー", str(e))

if __name__ == "__main__":
    root = tk.Tk()
    app = JSONFormatterApp(root)
    root.mainloop()

このGUIツールを実行するには: python json_formatter_gui.py

3. JSON整形のWebアプリケーション

from flask import Flask, render_template, request, jsonify
import json

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/format', methods=['POST'])
def format_json():
    try:
        data = request.json
        json_str = data.get('json', '')
        indent = data.get('indent', 4)
        sort_keys = data.get('sort_keys', False)
        
        # JSONを解析して整形
        parsed = json.loads(json_str)
        formatted = json.dumps(parsed, indent=indent, 
                              ensure_ascii=False, 
                              sort_keys=sort_keys)
        
        return jsonify({
            'success': True,
            'result': formatted
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'error': str(e)
        })

if __name__ == '__main__':
    app.run(debug=True)

使用方法: pip install flask でFlaskをインストールし、python app.py で実行

よくある質問

Q: Pythonで日本語を含むJSONを整形すると文字化けします

A: ensure_ascii=False オプションを指定し、ファイル操作時には encoding='utf-8' を指定してください。

Q: 大きなJSONファイルを処理するとメモリエラーが発生します

A: 大きなファイルには ijson ライブラリを使用して、ストリーミング処理を行ってください。または、ファイルを分割して処理することも検討してください。

Q: JSONの特定の部分だけを抽出して整形するには?

A: jq-pythonjsonpath-ng などのライブラリを使用すると、JSONの特定部分だけを抽出して処理できます。