JSON は、Web 上のデータ交換の事実上の標準になっています。 API、Web サービス、最新の Web サイトでは、サーバーとクライアント間のデータ送信に JSON が広く使用されています。
たとえば、BuiltWith によると、上位 70 の Web サイトの 10,000% 以上が JSON API を使用しています。 JSON 形式は、どのプログラミング言語でも簡単に生成および解析できます。
ただし、大規模な JSON ドキュメントから意味のある情報を効率的に抽出することは依然として困難な場合があります。ここで、JSONPath が登場します。JSONPath は、JSON データの検索と変換を簡素化するための特殊なクエリ言語です。
JSON の解析に関する問題
従来、JSON データは、Python dict などのネイティブ データ構造に完全に解析することによってアプリケーションで処理されます。データの小さなサブセットのみが必要な場合でも、JSON 応答全体を解析します。
このアプローチにはいくつかの欠点があります。
- パフォーマンスの低下 – 大きな JSON ファイルをオブジェクトに解析すると、計算コストが高くなります
- 高いメモリ使用量 – JSON 構造全体をメモリ内に保持する必要がある
- 冗長コード – 解析されたオブジェクトを詳しく調べるために、多くのループ/トラバーサル コードを作成する必要があることがよくあります。
別の方法は、正規表現を使用して、一致する JSON フラグメントを直接抽出することです。ただし、正規表現は複雑な入れ子構造になると厄介になります。また、動的なキー名や任意のネストの深さにも問題があります。
JSONPath は、生の解析や正規表現の一致と比較して、JSON をクエリするためのよりクリーンで簡潔な方法を提供します。
JSONPath の紹介
JSONPath 式は、JSON ドキュメントの一部にアクセスする方法を記述します。これは概念的には、XML 内の要素と属性のクエリを可能にする XPath に似ています。
//node/child::* - XPath for all child nodes
$.node.child - Equivalent JSONPath
JSONPath アプローチの利点は次のとおりです。
- 読みやすさ – クエリ式が分かりやすい
- 簡潔 – 冗長なトラバーサルコードは不要
- 柔軟性 – ルックアップ、フィルタ、ワイルドカード一致をサポート
- 性能 – 非常に最適化されたマッチングアルゴリズム
- スケーラビリティ – 巨大な JSON ドキュメントも高速に処理できます
JSONPath は、JSON からデータを抽出するためのシンプルでスケーラブルな代替手段を提供します。次に、それがどのように機能するかを見てみましょう。
JSONPath を使用した JSON のクエリ
JSONPath 式は、JSON 構造内で値を検索する方法を説明する文字列です。例えば:
data = {
"store": {
"books": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}
]
}
}
# All book titles
books = jsonpath(data, ‘$.store.books[*].title‘)
# Filter fiction books
fiction_books = jsonpath(data, ‘$.store.books[?(@.category=="fiction")].title‘)
JSONPath は次のような演算子を使用します。
.
– 子オペレーター[]
– 配列アクセス用の添字演算子*
– 一致するすべての要素のワイルドカード?()
– フィルタリング述語
これらを連鎖させると、複雑な JSON に対して効率的にクエリを実行できるようになります。
# Get all authors of books over 10 dollars
authors = jsonpath(data, ‘$.store.books[?(@.price > 10)].author‘)
深くネストされたループコードはもう必要ありません。 JSONPath は、JSON ツリー全体を完全に解析する必要なく、オブジェクトを直接照合します。
利用可能な JSONPath 演算子
JSONPath で使用できる演算子の概要は次のとおりです。
パス演算子
$
– ルートオブジェクト@
– 現在のオブジェクト.
or[]
– 子オペレーター..
– 子孫を再帰的に検索する
フィルター演算子
[?(<expression>)]
– オブジェクトのフィルタリング[(<condition>)]
– 条件に基づいてフィルタリングします
配列演算子
*
– ワイルドカードはすべての要素にインデックスを付けます[<index>]
– インデックス位置[start:end]
– 配列スライス[?(<condition>)]
– フィルター
投影用の演算子
[]
– 投影 – リストされたプロパティを抽出します[@]
– インデックス投影 – 配列を平坦化する
その他の演算子
|
– ユニオンオペレーター()
– 優先オペレーター,
– 複数の結果を区切ります
これらにより、単純なパス文字列を使用して JSON データのクエリ、フィルター、変換を柔軟に行うことができます。
XML の JSONPath と XPath
JSONPath は XPath と多くの類似点を共有しているため、この 2 つを比較する価値があります。
XPath
- XMLのクエリ言語
- XML ツリーの走査を許可します
- などの高度な軸をサポート
//
,/*
,//@
- XML ノードの抽出に使用します
JSONパス
- JSON と同等のクエリ言語
- XPath からインスピレーションを得た構文
- JSON は XML よりも表現的に単純であるため、構文が単純になります
- XML解析が不要なため迅速な実装が可能
どちらも、階層データ構造内のノードを選択できます。 JSONPath は、XML ではなく JSON に特化した XPath の簡易バージョンと考えることができます。
Python 用の人気のある JSONPath ライブラリ
JSONPath は多くのプログラミング言語に実装されています。 Python の一般的なライブラリには次のようなものがあります。
図書館 | Description |
---|---|
jsonpath-ng | 高度な機能を備えた高速な推奨ライブラリ |
jsonpath-rw | 準拠したリファレンス実装 |
jsonpath | シンプルな実装だが機能は限定的 |
ほとんどの用途では、 jsonpath-ng
コンプライアンス、機能、パフォーマンスの最適な組み合わせを提供します。
詳しい使い方を見ていきましょう。
jsonpath-ng を使用したクエリとフィルタリング
まず、jsonpath-ng をインストールします。
pip install jsonpath-ng
インポートするには:
from jsonpath_ng import jsonpath, parse
いくつかの例:
data = { "name": "John",
"age": 30,
"cars": [
{ "model": "BMW", "year": 2019 },
{ "model": "Tesla", "year": 2020 }
]
}
# Extract name
name = jsonpath(data, ‘$.name‘)
# Get first car
first_car = jsonpath(data, ‘$.cars[0]‘)
# Filter Tesla cars
teslas = jsonpath(data, ‘$.cars[?(@.model=="Tesla")]‘)
# Get all car years
years = jsonpath(data, ‘$..cars[*].year‘)
使用することもできます parse()
パフォーマンスを向上させるためにパスをコンパイルするメソッド:
parser = parse(‘$.cars[*].year‘)
for obj in json_data:
years = parser.find(obj)
print(years)
これにより、同じパスを複数の JSON ドキュメントに適用する場合に高速に動作します。
JSONデータのフィルタリング
JSONPath の最も強力な機能の 1 つは、フィルタリング構文です。
フィルターを使用すると、特定の基準に一致するオブジェクトを選択できます。例えば:
RecentCars = jsonpath(data, ‘$.cars[?(@.year > 2015)]‘)
これにより、2015 年以降の車が対象となります。
次のような比較を使用してフィルタリングできます。
- 数学的:
=
,!=
,>
,<=
, etc. - 論理的:
and
,or
,not
- 正規表現:
=~
,!=~
- 存在:
exists()
,?()
フィルタは組み合わせることもできます。
ElectricCars = jsonpath(data,
‘$.cars[?(@.year > 2010 && @.model =~ "Tesla|Volt")]`
)
これにより、2010 年以降に電気自動車が製造されるようになります。
JSON データの変換
データを抽出するだけでなく、JSONPath は次のような演算子を使用して JSON オブジェクトを変換できます。
[]
– オブジェクトの形状を変更する投影[@]
– 平坦化するための配列のインデックス付け
たとえば、車のデータを単純なリストに平坦化します。
all_models = jsonpath(data, ‘$..cars[*].model‘)
all_years = jsonpath(data, ‘$..cars[*].@year‘)
@
インデックスベースの投影を行います。
フィルター、プロジェクション、スライスを連鎖させると、JSON をプログラム的に再構築できます。
jsonpath-ng の高度な機能
jsonpath-ng によって提供される追加の高度な機能:
カスタム関数
カスタム関数を登録して JSONPath を拡張できます。
def format_price(x):
return f‘${x:,.2f}‘
jsonpath.register_custom_function(format_price, ‘format‘)
prices = jsonpath(data, ‘$.prices[*].format(@)‘)
これにより、複雑なデータ変換を JSONPath 式内で直接実装できるようになります。
キャッシュと最適化
jsonpath-ng は、パフォーマンスを向上させるためにクエリをコンパイルおよび最適化します。以下もサポートしています。
- 高速化のためのキャッシュ
- 不必要なスキャンを避けるための遅延マッチング
- 生産高の最適化
そのため、巨大な JSON ドキュメントに対しても良好なパフォーマンスを発揮します。
追加の演算子
その他の便利な演算子:
?()
– 存在チェック=~
,!=~
– 正規表現マッチングin
– チェックが含まれていますall
– 普遍的な量指定子
JSONPath メソッド
次のようなヘルパー メソッド:
find()
– 一致を返しますparse()
– コンパイルパス
一般的なクエリに対してよりシンプルな API を提供します。
WebスクレイピングにJSONPathを使用する
JSONPath の最も便利なアプリケーションの 1 つは、Web スクレイピング時のデータ抽出です。
最近の Web サイトは、データの送信に JSON に大きく依存しています。
- API – JSON は REST API の標準形式です
- 非同期データ – JSON は動的ページ更新のために JavaScript とともに使用されます
- ページのメタデータ – 多くの場合、サイト データは JSON としてスクリプトに保存されます
このすべての JSON を手動で解析するのは面倒です。 JSONPath を使用すると、必要なフラグメントのみを簡単にクエリできます。
たとえば、e コマース ページから商品データを抽出する方法は次のとおりです。
import requests
from jsonpath_ng import jsonpath, parse
# Fetch product page
url = "http://www.example.com/product/123"
response = requests.get(url)
# Extract JSON data
data = response.json()
# Parse out product details
name = jsonpath(data, ‘$.product.name‘)[0]
price = jsonpath(data, ‘$.product.price‘)[0]
image = jsonpath(data, ‘$.product.images[0]‘)
print(name, price, image)
重要なのは、手動処理ではなく、JSONPath を使用して必要なフィールドだけを直接取得することです。
一般的な使用例をいくつか示します。
- APIスクレイピング – REST API 応答からデータを抽出する
- JavaScript サイト – フロントエンドで使用されるクエリオブジェクト
- スマホアプリ – アプリトラフィックからの JSON データを解析する
- 動的コンテンツ – クライアント側の JavaScript からデータセットを構築する
JSONPath を使用すると、単純なパス文字列を使用して数千の JSON ドキュメントをスケーラブルにスクレイピングできます。
大きな JSON ファイルの解析
JSONPath は拡張性に優れていますが、巨大な JSON ドキュメントの解析には依然として課題が存在する可能性があります。
- Memory usage – 完全な JSON をメモリにロードする
- CPU負荷 – 複雑なドキュメントの解析にはプロセッサーが集中します
- ネットワーク転送 – 大きなドキュメントはより多くの帯域幅を意味します
大規模な JSON データを操作する場合のヒント:
- ストリーミング パーサーを使用して JSON の完全な読み込みを回避する
- パスをコンパイルします
parse()
再解析する代わりに - オブジェクト全体ではなく、必要な実際のフィールドのみを抽出します
-
laziness
不必要なオブジェクトのスキャンを避けるため - TB 以上の規模のデータを処理する場合は、強力なクラウド サーバー上で実行します
- 並列処理のために複数のクラスターに解析を分散します。
ほとんどの場合、JSONPath は適切に最適化されていれば、数十万のレコードを含む巨大な JSON ファイルからも効率的にデータを抽出できます。
私が JSONPath を使用するのが好きな理由
JSON データを幅広く扱う経験豊富なプロキシ エンジニアとして、私が JSONPath を使用するのが好きな理由は次のとおりです。
- 簡潔な構文 – パス式は従来の解析コードと比べて美しく簡潔です
- 生産性の向上 – 直感的な構文のおかげで、データベースをクエリするのと同じくらい簡単に JSON をクエリできます
- 堅牢なフィルタリング – 述語フィルターにより、一致するデータの選択が簡単になります
- 驚異的な高速パフォーマンス – jsonpath-ng は内部で非常に最適化されたアルゴリズムを使用しており、大規模なデータセットでも超高速のデータ抽出を可能にします
- メモリ効率が高い – JSON を選択的に解析するため、ネイティブ オブジェクトまで完全に解析する場合と比較してメモリ フットプリントが低くなります
- ウェブスクレイピングパワー – API および JavaScript 応答からの簡単なデータ抽出は、JSONPath が輝く場所です
jq や grep などのツールは優れていますが、ほとんどの JSON 解析ニーズには JSONPath の方がシンプルで洗練されていると思います。 jsonpath-ng のようなライブラリによる Python エコシステムのサポートにより、JSON データをスライスおよびダイシングするための私の頼りになる選択肢になります。
他の言語での JSONPath のサポート
ここでは Python に焦点を当ててきましたが、JSONPath は多くのプログラミング言語で利用できます。
- JavaScriptを – JSONPath プラス
- PHP – JSONパス
- Go – グジソン
- PostgreSQL – JSONパス
- R – jsonpath
JSON はユニバーサル データ形式であるため、どの言語からでも JSON を効率的にクエリできると便利です。ありがたいことに、JSONPath は広くサポートされています。
JSONPath が重要な理由
JSON は、Web API、マイクロサービス、フロントエンド アプリケーションにとって急速に不可欠なものになりました。 JSONPath は、JSON データの世界に XPath のようなクエリ機能をもたらします。
ネストされた JSON 値を簡単に抽出するための標準化されたパス言語を使用すると、次のような多くの利点があります。
- プラットフォームや言語にまたがる JSON データ抽出を簡素化
- 醜い正規表現解析に代わる読みやすい代替手段を提供します
- 応答全体を解析する必要なく、スケーラブルな Web スクレイピングを可能にします
- プロジェクションとフィルターを使用した複雑な変換が可能
- 巨大な JSON データセットを効率的にクエリする機能を解放します
- jq などの他の JSON ツールと一緒にパイプラインに自然に適合します
JSON が事実上のデータ交換形式として優位を保ち続ける中、一連の共通の JSONPath 演算子を使用すると、大規模な JSON ドキュメントをナビゲートする複雑さを軽減することができます。
まとめ
JSONPath は、簡潔なパス式を通じて JSON データから値を抽出および変換するエレガントな方法を提供します。
のような図書館 jsonpath-ng
JSONPath を Python プロジェクトに簡単に統合できます。
主な要点
- JSONPath を使用すると、「.」を使用して JSON 構造に簡単にクエリを実行できます。および「[]」演算子
- 述語を使用したプロパティ値によるフィルタリングは適切に拡張されます
- 変換は投影と配列拡張を使用して適用できます
- JSONPath により、スクレイピング時に JSON オブジェクト全体を解析する必要がなくなります
- 構文は、XML をクエリするための XPath 式に基づいてモデル化されています。
- 多くのプログラミング言語でサポートされています
JSON ベースの Web サービスを操作する場合、JSONPath は開発者のツールキットに不可欠なツールです。 JSONPath を使用すると、簡単な質問をして、複雑な JSON ドキュメントから必要なデータだけを取得できます。