Мы продолжаем знакомиться с возможностями API проекта «ГосЗатраты» в рамках нашего мини-курса, где мы пишем робота, который собирает данные о контрактах, анализирует их и присылает результаты нам на почту. Сегодня мы разберемся, на какие именно данные от «ГосЗатрат» мы можем рассчитывать.

Видео: Глеб Лиманский

Откроем наш проект в редакторе Visual Studio Code и в терминале запустим виртуальное окружение командой pipenv shell, которое мы создавали в одном из прошлых выпусков. В этом проекте у нас уже есть функция, которая на входе получает номер региона, а возвращает контракты, которые были заключены в этом регионе. Давайте используем эту функцию, а возвращенный результат запишем в JSON-файл. Так нам сегодня будет удобнее работать, потому что каждый раз, когда мы запускаем код, где есть строчка request.get, мы отправляем новый запрос к серверу API «ГосЗатрат». Мы не хотим злоупотреблять и зря расходовать их ресурсы. Поэтому запустим код один раз и запишем результат в JSON-файл, с которым дальше будем работать. Давайте закомментируем print(result) с помощью символа # в начале строки.

Чтобы сохранить JSON-файл, нам потребуется одноименная библиотека json. Импортируем ее с помощью import json. Затем запишем данные которые лежат в переменной result в файл под названием result.json и запустим наш код.

Можем проверить папку с проектом и увидеть, что файл создался. Перед тем, как начать с ним работать, давайте посмотрим, что лежит внутри этого файла — откроем его в браузере. В Firefox он открывается в удобном виде. Наш файл — это как бы словарь, в котором хранятся списки и другие словари. Главный ключ это contracts, сами контракты лежат в ключе data, они пронумерованы. Раскроем первый контракт и посмотрим, какие поля в нем есть и какие нам было бы интересно собрать. 

Нам интересны: ссылка на сам контракт (ведет на официальный портал госзакупок), дата подписания контракта, цена заключенного контракта, заказчик и данные о нем, поставщики и данные о них, данные о предметах контракта. Попробуем достать эти сущности из нашего файла.

Чтобы работать с файлом result.json, создадим в нашем проекте еще один, чтобы наша функция для получения контрактов осталась целой и невредимой — в следующих уроках мы будем ее дорабатывать. Создаем проект через терминал с помощью touch sandbox.py (sandbox это название нового проекта).

Как и в главном проекте main.py нам понадобится библиотека для работы с JSON, поэтому вводим в окне нового проекта import json. После этого откроем файл result.json.

Как мы уже говорили, JSON-файл состоит из списков и словарей, поэтому обращаться к нему мы будем соответственно — начнем с главного ключа contracts, затем в data, опускаясь вглубь до нужных нам полей. Назовем переменную data и посмотрим, что там лежит.

В терминале мы видим все наши контракты. Теперь перебирая циклом for contract in data каждый элемент в data мы можем обращаться к каждому контракту и доставать нужные нам поля. Например, попробуем достать URL с помощью print (contract[‘ContractUrl’]). Таким способом мы можем получать данные из любого ключа в файле. Дописываем ключи price и regionCode — получаем цены контрактов и регион заключения (в нашем случае он один и тот же).

Для распаковки таких словарей и списков мы можем использовать функцию, которую изучали в уроке про рекурсию. Эта функция принимает на вход два аргумента, один из них — ключ, по которому нужно найти значение, а второй — объект, в котором мы будем искать этот ключ и значение. Если объект будет равен None, функция вернет None

Перепишем наш код с использованием этой функции. В contract_url введем recurs_find_key (‘ContractUrl’, contract) и далее по образцу.

На пунктах customer, supplier и products (заказчик, поставщики и предметы контракта соответственно) остановимся отдельно. Если мы посмотрим в файл, то увидим, что внутри, например, заказчика есть еще словарь. Там лежит ИНН и название организации. 

Если мы распечатаем данные как есть, то увидим, что нам возвращаются словари, и с этим не очень удобно работать — нам нужны название и ИНН отдельно. Перепишем функцию так, чтобы она обращалась непосредственно к ключу customer по каждой из нужных нам деталей.

С supplier и products немного другая история. Поставщиков и продуктов по контракту может быть больше, чем один. Поэтому в suppliers в JSON-файле лежит список. Чтобы предусмотреть этот нюанс, нужно перебрать каждого поставщика и достать из него название и ИНН. Для этого сделаем словарь suppliers_dict и для каждого поставщика в списке создадим функцию, которая будет выводить ИНН и название организации. Дальше добавим это в наш словарь, где ключом будет ИНН, а значением — название. 

С products та же самая история. Сначала нам нужно получить имя каждой закупки. Снова воспользуемся нашей рекурсивной функцией, передадим ей список словарей, из которого будем доставать name. А дальше воспользуемся уже известными нам генераторами списков, чтобы получить список всех наименований, и превратим его в строчку функцией join, разделяя названия точкой с запятой. Назовем эту переменную subjects.

Используем recurs_find_key, чтобы достать ИНН и название
Там, где предметов больше одного, они перечислены через точку с запятой

Сегодня мы достали все необходимые значения, с которыми можем что-то делать, а в следующий раз усовершенствуем нашу функцию получения данных из API «ГосЗатрат». Если у вас возникли вопросы — как всегда, пишите в наш чат в Telegram.