Как парсить JSON в Python

Мы покажем вам весь процесс импорта json и его использования для парсинга JSON в Python, с полезной таблицей преобразований JSON-Python. Независимо от того, опытный вы разработчик Python или начинающий, с помощью этого пошагового руководства вы сможете научиться парсить JSON как профессионал!
4 min read
How to parse JSON data with 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 состоит из пар ключ-значение. Каждый ключ — это строка, а каждое значение может быть строкой, числом, булевым типом данных, нулем, массивом или объектом. Несмотря на то, что JSON похож на объект JavaScript, его можно использовать в любом языке программирования, включая Python.

Как работать с JSON в Python

Python поддерживает JSON с помощью модуля json, который является частью стандартной библиотеки Python. Это значит, что вам не нужно устанавливать дополнительную библиотеку для работы с JSON в Python. Вы можете импортировать json следующим образом:  

import json

Встроенная в Python библиотека json предоставляет полноценный API для работы с JSON. В частности, в ней есть две ключевые функции: loads и load. Первая позволяет парсить строчные данные JSON. Обратите внимание, что, несмотря на то, что ее название кажется множественным, окончание «s» означает «string». Таким образом, ее следует читать как «load-s». Вторая же предназначена для парсинга данных JSON в байты.  

С помощью этих двух методов json предоставляет вам возможность преобразовывать данные JSON в эквивалентные объекты Python — такие, как словари и списки, и наоборот. Кроме того, модуль json позволяет создавать пользовательские кодировщики и декодировщики для работы с конкретными типами данных.  

Читайте дальше, чтобы узнать, как использовать библиотеку json для парсинга JSON в Python!  

Парсинг JSON с помощью Python

Давайте рассмотрим несколько реальных примеров и научимся парсить JSON из разных источников в разнообразные структуры данных Python.

Преобразование JSON String в словарь Python

Предположим, что у вас есть некоторые данные JSON, хранящиеся в строке, и вы хотите преобразовать их в словарь Python. Вот как выглядят данные JSON:  

{
  "name": "iPear 23",
  "colors": ["black", "white", "red", "blue"],
  "price": 999.99,
  "inStock": true
}

А это его строковое представление в Python:

smartphone_json = '{"name": "iPear 23", "colors": ["black", "white", "red", "blue"], "price": 999.99, "inStock": true}'

Рассмотрите возможность использования в Python тройных кавычек для хранения длинных многострочных данных JSON в формате String.

Вы можете проверить, что слово smartphone содержит валидные в Python данные типа String, с помощью приведенной ниже строки:  

print(type(smartphone))

Это будет напечатано:

<class 'str'>

str расшифровывается как string и означает, что переменная 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'>

Фантастика! Теперь smartphone_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 содержит данные типа flat, она будет преобразована в соответствующий примитивный тип данных 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  
stringstr
number (integer)int
number (real)float
trueTrue
falseFalse
nullNone
arraylist
objectdict

Преобразование JSON API Response в словарь 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 json

url = "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(), как объяснялось ранее.  

Аналогичным образом можно добиться того же результата с помощью requests:  

import requests
import json

url = "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. Вот как выглядит ваш кастомный класс Smartphone в Python:  

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 в экземпляр smartphone:  

{
  "name": "iPear 23 Plus",
  "colors": ["black", "white", "gold"],
  "price": 1299.99,
  "inStock": false
}

Чтобы выполнить эту задачу, необходимо создать пользовательский декодер. Для этого необходимо расширить класс JSONDecoder и установить параметр object_hook в методе __init__. Присвойте ему имя метода класса, содержащего кастомную логику парсинга. В этом методе вы можете использовать значения, содержащиеся в стандартном словаре, возвращаемые 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-значение  
strstring 
intnumber (integer)
floatnumber (real)
Truetrue
False false
None null 
listarray
dictobject
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-представление словаря Python.

Обратите внимание, что вы также можете указать пользовательский кодер, однако демонстрация того, как это сделать, не является целью данной статьи. Чтобы узнать больше, обратитесь к официальной документации.  

Является ли стандартный модуль json лучшим ресурсом для парсинга JSON в Python?

Как и в случае с парсингом данных в целом, парсинг JSON сопряжен с проблемами, которые нельзя игнорировать. Например, в случае недействительного, неполного или нестандартного JSON модуль Python json не справится с задачей.  

Также необходимо быть осторожным при парсинге данных JSON из ненадежных источников. Это связано с тем, что вредоносная строка JSON может привести к поломке парсера или потреблению большого количества ресурсов. Это лишь некоторые из проблем, которые должен учитывать парсер Python JSON.

Вы можете ввести пользовательскую логику для решения этих конкретных случаев. В то же время, это может занять слишком много времени и привести к сложному и ненадежному коду. По этой причине вам следует рассмотреть коммерческий инструмент, облегчающий разбор JSON, например, Web Scraper IDE.  

Web Scraping IDE создана специально для разработчиков и обладает широким набором функций для парсинга JSON-контента и не только. Этот инструмент сэкономит вам массу времени и поможет обезопасить процесс разбора JSON. Кроме того, он поставляется с прокси Bright Data для анонимного вызова JSON API в случае наличия гео-ограничений.

Если вы спешите, вас также может заинтересовать наше предложение «Данные как услуга». С помощью этого сервиса вы можете попросить Bright Data предоставить вам индивидуальный набор данных, который соответствует вашим конкретным потребностям. Bright Data позаботится обо всем, от производительности до качества данных.  

Парсинг данных JSON еще никогда не был таким простым!

Заключение

Python позволяет вам анализировать данные JSON с помощью стандартного модуля json . Он предоставляет мощный API для сериализации и десериализации содержимого JSON. В частности, он предлагает методы json.read() и json.reads() для работы с файлами JSON и строками JSON соответственно. Здесь вы увидели, как использовать их для парсинга данных JSON в Python на нескольких реальных примерах. В то же время, вы также поняли ограничения этого подхода. Именно поэтому вы, возможно, захотите попробовать такое передовое и полнофункциональное коммерческое решение для парсинга данных, как Web Scraper IDE от Bright Data.