Привет! JSON быстро стал самым популярным форматом данных в современной сети. Как эксперт по веб-скрапингу с более чем 5-летним опытом, я видел, как JSON превратился из нишевого формата данных в лингва-франка для веб-API и веб-сайтов.
В этом посте я хочу познакомить вас с JMESPath — удобной библиотекой Python для анализа и обработки данных JSON. С появлением JSON JMESPath стал важным инструментом в моем наборе инструментов для парсинга веб-страниц.
Давайте на практике рассмотрим, как работает JMESPath, чтобы вы могли начать использовать его в своих скриптах Python и веб-скребках!
Быстрый рост JSON
Сначала давайте кратко обсудим почему JSON стал таким популярным В интернете. JSON означает «нотация объектов JavaScript» и неуклонно набирает популярность с момента его первой формализации в начале 2000-х годов.
Вот некоторая статистика по внедрению JSON:
- Более 70% современных веб-API используйте JSON для передачи данных
- Около 60% веб-сайтов теперь в некоторой степени обслуживает данные JSON
- Популярные сайты, такие как Twitter, Reddit и Facebook, предлагают API на основе JSON
- JSON готов в 4 раза популярнее чем XML для веб-данных в целом
JSON стал популярным форматом для веб-данных благодаря встроенной поддержке JavaScript, простому синтаксису, небольшому размеру файла и простоте анализа.
Для нас, парсеров, это означает, что нужные нам данные все чаще доступны в необработанных и структурированных документах JSON. Однако собрать эти полезные данные не всегда просто.
Несмотря на то, что JSON присутствует повсюду, необработанный JSON, полученный с сайтов, часто:
- огромный – содержит тонны лишних данных, которые нам не нужны
- Вложенные – с данными, скрытыми в сложных объектах и массивах
- Громоздкий – отсутствие легко извлекаемых полей и значений
Здесь на помощь приходит JMESPath!
Что такое JMESPath?
JMESPath (произносится как «путь Джеймса») — это язык запросов, специально разработанный для анализа данных JSON.
С помощью JMESPath вы пишете выражения для:
- Легко выбирать вложенные поля JSON
- Фильтрация массивов JSON
- Преобразование сложного JSON в более простые структуры
- Сортируйте, ограничивайте и преобразуйте JSON программно
JMESPath был разработан компанией Amazon (которая кое-что знает об обработке JSON!) и реализован для различных языков программирования.
Для Python мы используем jmespath
модуль, который предоставляет чистый API для использования JMESPath для анализа JSON.
Несколько примеров того, что вы можете сделать:
- Выберите определенные поля из документов JSON
- ФИЛЬТР массивы объектов JSON
- расплющить вложенный JSON в простые списки и значения
- Реформирование Данные JSON в формы, подходящие для Python
- Сортировать и Ограничивать массивы данных JSON
JMESPath позволяет легко работать даже с очень сложным JSON в Python.
Установка JMESPath в Python
JMESPath можно легко установить с помощью pip:
pip install jmespath
После установки импортируйте его в свои скрипты Python:
import jmespath
И вы готовы начать анализировать JSON!
Запрос JSON с помощью основ JMESPath
Ядро JMESPath выражает пути для детализации документов JSON.
Некоторые примеры основных выражений JMESPath:
Выберите name
поле из объекта JSON:
data = {‘name‘: ‘John‘, ‘age‘: 30}
jmespath.search(‘name‘, data)
# ‘John‘
Получите все имена из списка объектов JSON:
data = [
{‘name‘: ‘John‘, ‘age‘: 30},
{‘name‘: ‘Sarah‘, ‘age‘: 25}
]
jmespath.search(‘[*].name‘, data)
# [‘John‘, ‘Sarah‘]
Получите первый элемент из массива JSON:
data = {‘hobbies‘: [‘hiking‘, ‘reading‘, ‘coding‘]}
jmespath.search(‘hobbies[0]‘, data)
# ‘hiking‘
Как видите, JMESPath использует синтаксис, аналогичный JavaScript, с точечной записью и индексацией массива.
Теперь давайте посмотрим на некоторые более продвинутые функции.
Фильтрация массивов объектов JSON
Распространенной задачей является фильтрация массивов объектов JSON по условиям.
JMESPath упрощает фильтрацию массивов JSON.
Например, мы можем фильтровать пользователей по возрасту:
data = [
{‘name‘: ‘Sarah‘, ‘age‘: 25},
{‘name‘: ‘Mark‘, ‘age‘: 19},
{‘name‘: ‘John‘, ‘age‘: 30}
]
jmespath.search(‘[?age > `28`].name‘, data)
# [‘John‘]
Ассоциация [?age >
28]
Фильтр выбирает элементы, возраст которых больше 28.
Вы можете фильтровать строки, числа, вложенные объекты — практически все, что есть в ваших данных JSON.
Сведение и проецирование данных JSON
Еще одна чрезвычайно полезная функция JMESPath — сглаживание и проецирование JSON в другие формы.
Например, мы можем «свести» вложенный JSON в простой список, используя []
прогнозы:
data = {
‘product‘: {
‘id‘: 123,
‘name‘: ‘Widget‘,
‘colors‘: [‘blue‘,‘green‘]
}
}
jmespath.search(‘product.[id, name, colors[]]‘, data)
# [123, ‘Widget‘, ‘blue‘, ‘green‘]
Точно так же мы можем преобразовать объекты JSON в другие объекты JSON, используя {}
прогнозы:
data = {
‘product‘: {
‘id‘: 123,
‘name‘: ‘Super Widget‘,
‘price‘: 9.99,
‘dimensions‘: {
‘length‘: 10,
‘width‘: 5
}
}
}
jmespath.search("""
product.{
id: id,
name: name,
price_usd: price,
length_cm: dimensions.length,
width_cm: dimensions.width
}
""", data)
# {‘id‘: 123,
# ‘name‘: ‘Super Widget‘,
# ‘price_usd‘: 9.99,
# ‘length_cm‘: 10,
# ‘width_cm‘: 5}
Проекции позволяют легко преобразовать даже сложный вложенный JSON в простые форматы, такие как списки и словари, полезные для Python.
Сортировка, ограничение и нарезка массивов JSON
JMESPath предоставляет несколько полезных способов обработки массивов данных JSON:
data = [
{‘name‘: ‘Sarah‘, ‘age‘: 25},
{‘name‘: ‘Mark‘, ‘age‘: 19},
{‘name‘: ‘John‘, ‘age‘: 30}
]
# Sort by age
jmespath.search(‘[*].age | sort(@)‘, data)
# [19, 25, 30]
# Slice first 2 elements
jmespath.search(‘[*][:2]‘, data)
# [{‘name‘: ‘Sarah‘, ‘age‘: 25}, {‘name‘: ‘Mark‘, ‘age‘: 19}]
# Limit to 2 elements
jmespath.search(‘[*][0:2]‘, data)
# [{‘name‘: ‘Sarah‘, ‘age‘: 25}, {‘name‘: ‘Mark‘, ‘age‘: 19}]
Это позволяет нам брать большие массивы из документов JSON и извлекать только те биты, которые нам нужны.
JMESPath для парсинга веб-страниц
Теперь, когда мы рассмотрели основы запроса JSON с помощью JMESPath, давайте посмотрим, как это работает при парсинге веб-страниц.
В этом примере мы извлечем данные о листинге недвижимости с Realtor.com. Необходимые нам данные хранятся в теге сценария JSON на каждой странице листинга.
Вот пример листинга:
https://www.realtor.com/realestateandhomes-detail/335-30th-Ave_San-Francisco_CA_94121_M17833-49194
Сначала мы очистим страницу и получим JSON-скрипт:
import requests
from parsel import Selector
url = "https://www.realtor.com/realestateandhomes-detail/335-30th-Ave_San-Francisco_CA_94121_M17833-49194"
response = requests.get(url)
selector = Selector(text=response.text)
json_data = selector.css(‘script#__NEXT_DATA__::text‘).get()
Это дает нам объект JSON с тысячи строк, содержащих все данные о листинге.
Вот лишь малая часть:
{
"building": {
"rooms": {
"baths": 4,
"beds": 4,
"total_rooms": null,
"room_type": null
},
"building_size": {
"size": 3066,
"units": null
},
"parking": {
"spaces": null,
"description": null,
"parking_type": null
}
}
// and lots more!
}
Вместо того, чтобы анализировать этот огромный объект, мы можем использовать JMESPath для запроса только того, что нам действительно нужно:
import json
import jmespath
data = json.loads(json_data)
result = jmespath.search("""
{
id: listing_id,
facts: {
beds: building.rooms.beds,
baths: building.rooms.baths,
sqft: building.building_size.size
},
price: list_price
}
""", data)
print(result)
Это печатает только те поля, которые нам нужны:
{‘id‘: ‘2950457253‘,
‘facts‘: {‘beds‘: 4, ‘baths‘: 4, ‘sqft‘: 3066},
‘price‘: 2995000}
С помощью JMESPath мы смогли проанализировать тысячи строк JSON в чистый словарь Python, содержащий только те поля, которые нам нужны.
Теперь мы могли легко собирать данные по всем спискам, перебирая URL-адреса и извлекая JSON с помощью JMESPath на каждой итерации.
Сравнение с другими парсерами JSON
В Python есть еще несколько популярных вариантов синтаксического анализа JSON:
- Путь JSON – Язык запросов аналогичен JMESPath, но менее полнофункциональный.
- jq – Мощный процессор JSON, но требует изучения уникального синтаксиса.
- json.load() – Встроенный парсер Python JSON, но требует большого количества кода.
По моему опыту, JMESPath обеспечивает наилучший баланс для простого, но мощного анализа JSON в Python.
Некоторые ключевые преимущества JMESPath:
- Краткий синтаксис запроса
- Высокая производительность для больших документов JSON
- Легко выучить выражения
- Отличная документация и поддержка сообщества
- Сложная проекция объектов
- Специально создан для JSON
Для быстрого анализа JSON, полученного из Интернета, я предпочитаю JMESPath.
Дополнительные ресурсы JMESPath
Вот еще несколько замечательных ресурсов для освоения JMESPath:
- Примеры JMESPath – Официальный репозиторий с большим количеством фрагментов кода.
- Учебные пособия по JMESPath – Видеопрохождение выражений
- Спецификация JMESPath – Полная языковая грамматика
- Библиотеки расширений JMESPath – Инструменты, расширяющие функциональность JMESPath.
В частности, я рекомендую играть с Терминал JMESPath где вы можете быстро опробовать выражения на примерах данных JSON.
Давайте разберем весь JSON!
Спасибо, что присоединились ко мне в этом кратком введении в анализ JSON с помощью JMESPath в Python. Надеюсь, вы нашли это полезным!
Вот краткий обзор того, что мы рассмотрели:
- Что такое JMESPath? – Язык запросов для фильтрации, выравнивания и преобразования данных JSON.
- Почему это важно – JSON стал доминирующим форматом веб-данных.
- Как установить –
pip install jmespath
- Основы запросов – Точечная запись, индексация массивов, фильтры и т. д.
- Сглаживание/проецирование – Изменение формы сложного вложенного JSON.
- Сортировка/нарезка – Обработка массивов JSON.
- Пример парсинга веб-страниц – Извлечение данных с сайта Realtor.com с помощью JMESPath.
С появлением JSON наличие такого инструмента, как JMESPath, может значительно упростить извлечение полезных данных из очищенных веб-сайтов и API.
Дайте мне знать, если у вас есть еще вопросы! Я всегда рад помочь коллегам-парсерам.
Теперь выйдите и используйте JMESPath, чтобы собрать весь этот сочный JSON в сети!