перейти к содержанию

Краткое введение в анализ JSON с помощью JSONPath в Python

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-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 доступен на многих языках программирования:

Поскольку 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.

Присоединяйтесь к беседе

Ваш электронный адрес не будет опубликован. Обязательные поля помечены * *