JSON стал фактическим стандартом обмена данными в сети. API, веб-сервисы и современные веб-сайты широко используют JSON для отправки данных между серверами и клиентами.
Например, по данным BuildingWith, более 70% из 10,000 XNUMX лучших веб-сайтов используют API-интерфейсы JSON. Формат JSON легко генерировать и анализировать на любом языке программирования.
Однако эффективное извлечение значимой информации из больших документов JSON по-прежнему может быть сложной задачей. Здесь на помощь приходит JSONPath — специализированный язык запросов, упрощающий поиск и преобразование данных JSON.
Проблема с разбором JSON
Традиционно данные JSON обрабатываются в приложениях путем полного анализа их в собственные структуры данных, такие как словари Python. Вы будете анализировать весь ответ JSON, даже если вам нужна только небольшая часть данных.
У этого подхода есть некоторые недостатки:
- Низкая производительность – Разбор больших файлов JSON на объекты требует больших вычислительных затрат.
- Высокое использование памяти – Вся структура JSON должна храниться в памяти.
- Подробный код – Вам часто приходится писать много кода цикла/обхода, чтобы копаться в анализируемых объектах.
Альтернативой является использование регулярных выражений для прямого извлечения соответствующих фрагментов JSON. Однако регулярное выражение становится запутанным из-за сложных вложенных структур. Он также борется с динамическими именами ключей или произвольной глубиной вложенности.
JSONPath обеспечивает более чистый и лаконичный способ запроса JSON по сравнению с необработанным анализом или сопоставлением регулярных выражений.
Представляем JSONPath
Выражения JSONPath описывают, как получить доступ к частям документа JSON. Концептуально он похож на XPath, который позволяет запрашивать элементы и атрибуты в XML:
//node/child::* - XPath for all child nodes
$.node.child - Equivalent JSONPath
Некоторые преимущества подхода JSONPath:
- читабельность – Выражения запроса легко понять.
- краткость – Нет необходимости в подробном коде обхода
- Трансформируемость – Поддерживает поиск, фильтры, совпадения с подстановочными знаками.
- Перфоманс – Очень оптимизированные алгоритмы сопоставления
- Масштабируемость – Может быстро обрабатывать даже огромные документы JSON.
JSONPath предоставляет простую масштабируемую альтернативу извлечению данных из JSON. Далее давайте разберемся, как это работает.
Запрос JSON с помощью JSONPath
Выражение 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 с использованием простых строк пути.
JSONPath против XPath для XML
Поскольку JSONPath имеет много общего с XPath, стоит сравнить их:
XPath
- Язык запросов для XML
- Позволяет перемещаться по XML-дереву.
- Поддерживает расширенные оси, такие как
//
,/*
,//@
- Используйте для извлечения узлов XML
путь JSON
- Эквивалентный язык запросов для JSON
- Синтаксис, вдохновленный XPath
- Более простой синтаксис, поскольку JSON визуально проще, чем XML.
- Быстрая реализация, поскольку не требуется синтаксический анализ XML
Оба позволяют выбирать узлы в иерархических структурах данных. JSONPath можно считать упрощенной версией XPath, специализированной для JSON, а не XML.
Популярные библиотеки JSONPath для Python
JSONPath реализован для многих языков программирования. Некоторые популярные библиотеки для Python:
Библиотека | Описание |
---|---|
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 является синтаксис фильтрации.
Фильтры позволяют выбирать объекты, соответствующие определенным критериям. Например:
RecentCars = jsonpath(data, ‘$.cars[?(@.year > 2015)]‘)
Это автомобили новее 2015 года выпуска.
Вы можете фильтровать, используя сравнения, например:
- математический:
=
,!=
,>
,<=
, и т.д. - Логические:
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 для распространенных запросов.
Использование JSONPath для парсинга веб-страниц
Одно из наиболее полезных применений JSONPath — извлечение данных при парсинге веб-страниц.
Современные веб-сайты в значительной степени полагаются на JSON для передачи данных:
- API – JSON — стандартный формат для REST API.
- Асинхронные данные – JSON используется с JavaScript для динамических обновлений страниц.
- Метаданные страницы – Данные сайта часто хранятся в скриптах в формате JSON.
Анализировать весь этот JSON вручную было бы затруднительно. JSONPath позволяет легко запрашивать только те фрагменты, которые вам нужны.
Например, вот как извлечь данные о продукте со страницы электронной торговли:
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 по-прежнему может вызывать проблемы:
- Использование памяти – Загрузка полного JSON в память
- Загрузка процессора – Анализ сложных документов требует интенсивного использования процессора.
- Сетевая передача – Большие документы означают большую пропускную способность
Несколько советов при работе с большими данными JSON:
- Используйте потоковые парсеры, чтобы избежать полной загрузки JSON.
- Скомпилируйте пути с помощью
parse()
вместо повторного анализа - Извлекайте только необходимые поля вместо полных объектов.
- Используйте
laziness
чтобы избежать ненужного сканирования объектов - Работайте на мощных облачных серверах при обработке данных масштаба TB+.
- Распределите синтаксический анализ по кластерам для параллельной обработки.
В большинстве случаев JSONPath при правильной оптимизации может эффективно извлекать данные даже из огромных файлов JSON с сотнями тысяч записей.
Почему мне нравится использовать JSONPath
Как опытный инженер-прокси, много работающий с данными JSON, я люблю использовать JSONPath:
- Краткий синтаксис – Выражения пути очень лаконичны по сравнению с традиционным кодом синтаксического анализа.
- Увеличение производительности – Вы можете запрашивать JSON так же легко, как запросить базу данных, благодаря интуитивно понятному синтаксису.
- Надежная фильтрация – Фильтры предикатов упрощают выбор совпадающих данных.
- Молниеносная производительность – jsonpath-ng использует чрезвычайно оптимизированные алгоритмы, которые позволяют молниеносно извлекать данные даже из больших наборов данных.
- Эффективная память – Поскольку он анализирует JSON выборочно, объем памяти невелик по сравнению с полным анализом собственных объектов.
- Возможности парсинга веб-страниц – Простое извлечение данных из API и ответов JavaScript – вот где преимущество JSONPath.
Хотя такие инструменты, как jq и grep, великолепны, я считаю, что JSONPath проще и элегантнее подходит для большинства моих потребностей в анализе JSON. Поддержка экосистемы Python с такими библиотеками, как jsonpath-ng, делает его моим идеальным выбором для нарезки данных JSON.
Поддержка JSONPath на других языках
Хотя мы сосредоточились на Python, JSONPath доступен на многих языках программирования:
- JavaScript – JSONPath Плюс
- PHP – путь JSON
- Go – Гджсон
- PostgreSQL – путь JSON
- R – jsonpath
Поскольку JSON является универсальным форматом данных, полезно иметь возможность эффективно запрашивать его на любом языке. К счастью, JSONPath широко поддерживается.
Почему JSONPath имеет значение
JSON быстро стал незаменимым для веб-API, микросервисов и интерфейсных приложений. JSONPath привносит в мир данных JSON возможности запросов, подобные XPath.
Наличие стандартизированного языка путей для простого извлечения вложенных значений JSON имеет множество преимуществ:
- Упрощает извлечение данных JSON на разных платформах и языках.
- Предоставляет удобочитаемую альтернативу уродливому анализу регулярных выражений.
- Обеспечивает масштабируемый парсинг веб-страниц без необходимости анализа целых ответов.
- Позволяет сложные преобразования с использованием проекций и фильтров.
- Открывает возможность эффективно запрашивать огромные наборы данных JSON.
- Естественно вписывается в конвейеры вместе с другими инструментами JSON, такими как jq.
Поскольку JSON продолжает доминировать как формат обмена данными де-факто, наличие набора общих операторов JSONPath поможет упростить навигацию по большим документам JSON.
Заключение
JSONPath предоставляет элегантный способ извлечения и преобразования значений из данных JSON с помощью кратких выражений пути.
Библиотеки как jsonpath-ng
упростите интеграцию JSONPath в ваши проекты Python.
Программа вебинара:
- JSONPath позволяет легко выполнять запросы к структурам JSON, используя '.' и операторы '[]'
- Фильтрация по значениям свойств с использованием предикатов хорошо масштабируется
- Преобразования можно применять с помощью проекций и расширения массива.
- JSONPath позволяет избежать необходимости анализировать целые объекты JSON при очистке.
- Синтаксис создан по образцу выражений XPath для запроса XML.
- Поддерживается на многих языках программирования
Для работы с веб-сервисами на основе JSON JSONPath — незаменимый инструмент в наборе инструментов любого разработчика. JSONPath позволяет задавать простые вопросы и получать только необходимые данные из сложных документов JSON.