Как парсить JSON в Python
Введение в JSON в Python
Прежде чем приступить к парсингу JSON в Python, давайте разберемся, что такое JSON и как его использовать в Python.
Что такое JSON?
JSON, сокращенно от JavaScript Object Notation, - это легкий формат обмена данными. Он прост для чтения и записи человеком и легко парсится и генерируется машинами. Это делает его одним из самых популярных форматов данных. В частности, JSON стал "языком веба", поскольку широко используется для передачи данных между серверами и веб-приложениями через API.
Ниже приведен пример JSON:
{
"name": "Maria Smith",
"age": 32,
"isMarried": true,
"hobbies": ["reading", "jogging"],
"address": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"zip": "12345"
},
"phoneNumbers": [
{
"type": "home",
"number": "555-555-1234"
},
{
"type": "work",
"number": "555-555-5678"
}
],
"notes": null
}
Как видно, JSON состоит из пар ключ-значение. Каждый ключ - это строка, а каждое значение может быть строкой, числом, булевой функцией, null, массивом или объектом. Несмотря на то, что JSON похож на объект JavaScript, его можно использовать в любом языке программирования, включая Python.
Как работать с JSON в Python
Python поддерживает JSON через модуль json, который является частью стандартной библиотеки Python. Это означает, что для работы с JSON в Python не нужно устанавливать какую-либо дополнительную библиотеку. Импортировать json можно следующим образом:
import json
Встроенная библиотека Python json предоставляет полный API для работы с JSON. В частности, в ней есть две ключевые функции: loads и load. Функция loads позволяет парсить данные JSON из строки. Обратите внимание, что, несмотря на то, что ее название кажется множественным, окончание "s" означает "string". Таким образом, ее следует читать как "load-s". С другой стороны, функция load предназначена для парсинга JSON-данных на байты.
С помощью этих двух методов json позволяет преобразовывать данные JSON в эквивалентные объекты Python, такие как словари и списки, и наоборот. Кроме того, модуль json позволяет создавать собственные кодировщики и декодировщики для работы с конкретными типами данных.
Продолжайте читать и узнайте, как использовать библиотеку json для разбора JSON-данных в Python!
Парсинг JSON-данных с помощью Python
Давайте рассмотрим несколько реальных примеров и научимся парсить данные JSON из различных источников в различные структуры данных Python.
Преобразование строки JSON в словарь Python
Предположим, что у вас есть некоторые данные JSON, хранящиеся в строке, и вы хотите преобразовать их в словарь Python. Вот как выглядят данные в формате JSON:
{
"name": "iPear 23",
"colors": ["black", "white", "red", "blue"],
"price": 999.99,
"inStock": true
}
А вот его строковое представление на языке Python:
smartphone_json = '{"name": "iPear 23", "colors": ["черный", "белый", "красный", "синий"], "цена": 999.99, "inStock": true}'
Для хранения длинных многострочных строк JSON следует использовать соглашение Python о тройных кавычках.
Проверить, что smartphone содержит корректную строку Python, можно с помощью следующей строки:
print(type(smartphone))
В результате будет выведено:
<class 'str'>
str означает "строка" и означает, что переменная smartphone имеет тип текстовой последовательности.
Парсируйте JSON-строку, содержащуюся в smartphone, на Python-словарь с помощью метода json.loads() следующим образом:
import json
# JSON string
smartphone_json = '{"name": "iPear 23", "colors": ["black", "white", "red", "blue"], "price": 999.99, "inStock": true}'
# from JSON string to Python dict
smartphone_dict = json.loads(smartphone_json)# verify the type of the resulting variable
print(type(smartphone_dict)) # dict
Если выполнить этот фрагмент, то получится:
<class 'dict'>
Фантастика! Теперь smart_dict содержит корректный словарь Python!
Таким образом, для преобразования JSON-строки в словарь Python достаточно передать корректную JSON-строку в json.loads().
Теперь к полям полученного словаря можно обращаться как обычно:
product = smartphone_dict['product'] # smartphone
priced = smartphone['price'] # 999.99
colors = smartphone['colors'] # ['black', 'white', 'red', 'blue']
Следует помнить, что функция json.loads() не всегда возвращает словарь. В частности, возвращаемый тип данных зависит от входной строки. Например, если строка JSON содержит плоское значение, то оно будет преобразовано в соответствующее значение примитива Python:
import json
json_string = '15.5'
float_var = json.loads(json_string)print(type(float_var)) # <class 'float'>
Аналогично, строка JSON, содержащая список массивов, превратится в список Python:
import json
json_string = '[1, 2, 3]'
list_var = json.loads(json_string)
print(json_string) # <class 'list'>
Посмотрите на приведенную ниже таблицу преобразования, чтобы увидеть, как значения JSON преобразуются в данные Python с помощью json:
| Значение JSON | Данные Python |
| string | str |
| number (integer) | int |
| number (real) | float |
| true | True |
| false | False |
| null | None |
| array | list |
| object | dict |
Преобразование JSON-ответа API в словарь Python
Предположим, что вам необходимо создать API и преобразовать его JSON-ответ в словарь Python. В приведенном ниже примере мы вызовем следующую конечную точку API из проекта {JSON} Placeholder, чтобы получить некоторые фальшивые JSON-данные:
https://jsonplaceholder.typicode.com/todos/1
Этот RESTFul API возвращает приведенный ниже ответ в формате JSON:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Вы можете вызвать этот API с помощью модуля urllib из стандартной библиотеки и преобразовать полученный JSON в словарь Python следующим образом:
import urllib.request
import jsonurl = "https://jsonplaceholder.typicode.com/todos/1"
with urllib.request.urlopen(url) as response:
body_json = response.read()body_dict = json.loads(body_json)
user_id = body_dict['userId'] # 1
urllib.request.urlopen() выполняет вызов API и возвращает объект HTTPResponse. Его метод read() используется для получения тела ответа body_json, которое содержит ответ API в виде строки JSON. Наконец, эта строка может быть разобрана в Python-словарь с помощью json.loads(), как было описано выше.
Аналогичным образом можно добиться того же результата при работе с запросами:
import requests
import jsonurl = "https://jsonplaceholder.typicode.com/todos/1"
response = requests.get(url)body_dict = response.json()
user_id = body_dict['userId'] # 1
Обратите внимание, что метод .json() автоматически преобразует объект ответа, содержащий данные в формате JSON, в соответствующую структуру данных Python.
Отлично! Теперь вы знаете, как разобрать JSON-ответ API на языке Python с помощью urllib и requests.

Загрузка JSON-файла в словарь Python
Предположим, что у вас есть некоторые JSON-данные, хранящиеся в файле smartphone.json, как показано ниже:
{
"name": "iPear 23",
"colors": ["black", "white", "red", "blue"],
"price": 999.99,
"inStock": true,
"dimensions": {
"width": 2.82,
"height": 5.78,
"depth": 0.30
},
"features": [
"5G",
"HD display",
"Dual camera"
]
}
Ваша цель - прочитать JSON-файл и загрузить его в словарь Python. Достичь этого можно с помощью приведенного ниже фрагмента:
import json
with open('smartphone.json') as file:
smartphone_dict = json.load(file)print(type(smartphone_dict)) # <class 'dict'>
features = smartphone_dict['features'] # ['5G', 'HD display', 'Dual camera']
Встроенная библиотека open() позволяет загрузить файл и получить соответствующий ему файловый объект. Затем метод json.read() десериализует текстовый или двоичный файл, содержащий JSON-документ, в эквивалентный объект Python. В данном случае smartphone.json становится словарем Python.
Прекрасно, разбор JSON-файла в Python занимает всего несколько строк кода!
От JSON-данных к пользовательскому объекту Python
Теперь необходимо разобрать некоторые данные JSON в пользовательский класс Python. Вот как выглядит ваш пользовательский Python-класс Smartphone:
class Smartphone:
def __init__(self, name, colors, price, in_stock):
self.name = name
self.colors = colors
self.price = price
self.in_stock = in_stock
Здесь задача состоит в том, чтобы преобразовать следующую строку JSON в экземпляр смартфона:
{
"name": "iPear 23 Plus",
"colors": ["black", "white", "gold"],
"price": 1299.99,
"inStock": false
}
Для решения этой задачи необходимо создать собственный декодер. Для этого необходимо расширить класс JSONDecoder и установить в методе __init__ параметр object_hook. Присвойте ему имя метода класса, содержащего пользовательскую логику парсинга. В этом методе синтаксического анализа можно использовать значения, содержащиеся в стандартном словаре, возвращаемом функцией json.read(), для инстанцирования объекта Smartphone.
Определите пользовательский SmartphoneDecoder, как показано ниже:
import json
class SmartphoneDecoder(json.JSONDecoder):
def __init__(self, object_hook=None, *args, **kwargs):
# set the custom object_hook method
super().__init__(object_hook=self.object_hook, *args, **kwargs)# class method containing the
# custom parsing logic
def object_hook(self, json_dict):
new_smartphone = Smartphone(
json_dict.get('name'),
json_dict.get('colors'),
json_dict.get('price'),
json_dict.get('inStock'),
)return new_smartphone
Обратите внимание, что для чтения значений словаря в пользовательском методе object_hook() следует использовать метод get(). Это позволит избежать ошибок KeyErrors при отсутствии ключа в словаре. Вместо этого будут возвращены значения None.
Теперь можно передать класс SmartphoneDecoder в параметр cls в json.loads() для преобразования JSON-строки в объект Smartphone:
import json
# class Smartphone:
# ...# class SmartphoneDecoder(json.JSONDecoder):
# ...smartphone_json = '{"name": "iPear 23 Plus", "colors": ["black", "white", "gold"], "price": 1299.99, "inStock": false}'
smartphone = json.loads(smartphone_json, cls=SmartphoneDecoder)
print(type(smartphone)) # <class '__main__.Smartphone'>
name = smartphone.name # iPear 23 Plus
Аналогично можно использовать SmartphoneDecoder с json.load():
smartphone = json.load(smartphone_json_file, cls=SmartphoneDecoder)
Теперь вы знаете, как парсить данные JSON в пользовательские объекты Python!
Преобразование данных Python в JSON
Можно пойти и по другому пути и преобразовать структуры и примитивы данных Python в JSON. Это возможно благодаря функциям json.dump() и json.dumps(), которые следуют приведенной ниже таблице преобразования:
| Данные Python | Значение JSON |
| str | string |
| int | number (integer) |
| float | number (real) |
| True | true |
| False | false |
| None | null |
| list | array |
| dict | object |
| Null | None |
json.dump() позволяет записать строку JSON в файл, как в следующем примере:
import json
user_dict = {
"name": "John",
"surname": "Williams",
"age": 48,
"city": "New York"
}# serializing the sample dictionary to a JSON file
with open("user.json", "w") as json_file:
json.dump(user_dict, json_file)
Этот фрагмент сериализует переменную Python user_dict в файл user.json.
Аналогично, json.dumps() преобразует переменную Python в эквивалентную ей строку JSON:
import json
user_dict = {
"name": "John",
"surname": "Williams",
"age": 48,
"city": "New York"
}user_json_string = json.dumps(user_dict)
print(user_json_string)
Обратите внимание, что вы также можете указать собственный кодировщик, но показ того, как это сделать, не является целью данной статьи. Для получения более подробной информации обратитесь к официальной документации.
Является ли стандартный модуль json лучшим ресурсом для парсинга JSON в Python?
Как и в случае с разбором данных, при парсинге JSON возникают проблемы, которые нельзя упускать из виду. Например, в случае недействительного, неполного или нестандартного JSON модуль Python json окажется неэффективным.
Кроме того, необходимо быть осторожным при парсинге JSON-данных из недоверенных источников. Это связано с тем, что вредоносная JSON-строка может привести к поломке парсера или потреблению большого количества ресурсов. Это лишь одна из проблем, которые должен учитывать парсер JSON на Python.
Для решения этих проблем можно использовать пользовательскую логику. В то же время это может занять слишком много времени и привести к появлению сложного и ненадежного кода. Поэтому следует обратить внимание на коммерческий инструмент, облегчающий парсинг JSON, например, Web Scraper IDE.
Web Scraping IDE создана специально для разработчиков и обладает широким набором функций для парсинга JSON-контента и не только. Этот инструмент поможет вам сэкономить массу времени и обеспечить безопасность процесса парсинга JSON.
Заключение
Python позволяет парсить данные в формате JSON с помощью стандартного модуля json. Он предоставляет мощный API для сериализации и десериализации JSON-контента. В частности, он предлагает методы json.read() и json.reads() для работы с файлами JSON и строками JSON, соответственно. Здесь на нескольких реальных примерах вы увидели, как использовать их для парсинга JSON-данных в Python. В то же время вы поняли и ограничения такого подхода.
См. также: Разработка ПО, Разработка веб-приложений: Ресурсы, лучшие практики и как это сделать, Облачная разработка / интеграция.


