Выгрузим координаты избирательных участков Москвы, обратившись к API сайта mos.ru.
Для отправления запроса нам понадобится модуль requests
:
import requests
Как выглядят запросы с API, если их отправлять не автоматически, через Python, а формировать вручную? Это просто ссылки особого вида, где помимо основной ссылки добавляются параметры и их значения. Например, можно написать какой-нибудь текстовый шаблон такого вида:
"https://myapi.ru/data/id={id0}?key={key0}",
где вместо id0
будет подставляться идентификатор набора данных, который нас интересует, а вместо key0
– ключ доступа к API.
Какие параметры могут присутствовать в запросе, зависит от устройства конкректного API. API можно рассматривать как базу данных с разработанным интерфейсом. Пользователь должен четко понимать, какие данные его интересуют, но при этом он не обязан знать SQL или другие языки для обращения к базам данных, достаточно посмотреть документацию к API и понять, какие параметры подставить в текстовую строку с запросом.
Если API не полностью открытый, к нему нужно получить доступ. Обычно процедура его получения описывается в документации к API. После регистрации пользователь получает ключ доступа – обычный набор символов, похожий на пароль, который нужно всегда указывать в запросе. Получим ключ доступа для API mos.ru по инструкции и сохраним его в Python:
key = "9b36f3ab185cbac617668968752505d9"
Если посмотрим на документацию, заметим, что все запросы к API начинаются со слова GET
. В Python это будет реализовываться с помощью функции get()
из модуля requests
. Для примера запросим текущую версию API:
resp = requests.get("https://apidata.mos.ru/version")
resp
<Response [200]>
Сам объект resp
от нас скрыт, код [200]
означает, что ответ получен. Вызовем результат в формате json()
:
d = resp.json()
d['Version'] # версия
1
Если снова обратимся к документации, заметим, что в ней описаны все параметры, которые мы можем задать в запросе. Сформируем строку запроса к набору данных с id = 961 (нам нужен этот набор с данными по УИКам Москвы:
# rows – выдает все строки
# доклеиваем ключ к API – без него не даст доступ
resp = requests.get("https://apidata.mos.ru/v1/datasets/961/rows?api_key="
+key)
resp # все ок, есть ответ на запрос
<Response [200]>
Снова вызовем результат в формате json
, в данном случае это список словарей:
# один словарь – один УИК
results = resp.json()
Посмотрим на первый элемент – первый УИК в таблице на сайте:
results[0]
{'global_id': 1006662927, 'Number': 1, 'Cells': {'global_id': 1006662927, 'District_RF': 'район Орехово-Борисово Южное', 'PollStationNumber': 1981, 'PollStationName': 'Избирательный участок № 1981', 'PollStationAddress': 'Воронежская улица, дом 46, корпус 3', 'PollStationAddressExtraInfo': 'ГБОУ СОШ № 949', 'PollStationContactPhone': '(495) 398-89-12', 'PollPlaceAddress': 'Воронежская улица, дом 46, корпус 3', 'PollPlaceAddressExtraInfo': 'ГБОУ СОШ № 949', 'PollPlaceContactPhone': '(495) 398-89-12', 'PolIAddressesList': [{'PolIAddressesList': 'Гурьевский проезд, дом 29, корпус 1'}, {'PolIAddressesList': 'Гурьевский проезд, дом 31, корпус 1'}, {'PolIAddressesList': 'Гурьевский проезд, дом 31, корпус 2'}, {'PolIAddressesList': 'Гурьевский проезд, дом 35/58'}], 'AdmArea_RF': 'Южный административный округ', 'geoData': {'type': 'Point', 'coordinates': [37.753847, 55.608810999999996]}}}
Теперь можем вызывать любые поля – любые записи по ключам в словаре. Например, вытащим отсюда адреса, относящиеся к УИКу:
# ключ Cells и внутри ключ PolIAddressesList
results[0]['Cells']['PolIAddressesList']
[{'PolIAddressesList': 'Гурьевский проезд, дом 29, корпус 1'}, {'PolIAddressesList': 'Гурьевский проезд, дом 31, корпус 1'}, {'PolIAddressesList': 'Гурьевский проезд, дом 31, корпус 2'}, {'PolIAddressesList': 'Гурьевский проезд, дом 35/58'}]
Теперь вытащим координаты:
# ключ Cells, внутри ключ geoData и внутри ключ coordinates
results[0]['Cells']['geoData']['coordinates']
[37.753847, 55.608810999999996]
Теперь осталось запустить цикл по всем элементам списка и сохранить номер участка и его кооржинаты в список:
dat = []
for i in results:
uik = i['Cells']['PollStationNumber']
lat, lon = i['Cells']['geoData']['coordinates']
dat.append([uik, lat, lon])
Превратим список списков в датафрейм:
import pandas as pd
df = pd.DataFrame(dat)
df.head()
0 | 1 | 2 | |
---|---|---|---|
0 | 1981 | 37.753847 | 55.608811 |
1 | 932 | 37.822819 | 55.795013 |
2 | 1014 | 37.827419 | 55.754405 |
3 | 1982 | 37.753847 | 55.608811 |
4 | 1310 | 37.823242 | 55.694921 |
Переименуем столбцы:
df.columns = ['uik', 'lat', 'lon']
df.head()
uik | lat | lon | |
---|---|---|---|
0 | 1981 | 37.753847 | 55.608811 |
1 | 932 | 37.822819 | 55.795013 |
2 | 1014 | 37.827419 | 55.754405 |
3 | 1982 | 37.753847 | 55.608811 |
4 | 1310 | 37.823242 | 55.694921 |
Готово!