Если вам зачем-то понадобилась полная адресная база России, то самый простой и дешевый способ ее заполучить — это скачать на сайте налоговой. Да, вот так вот просто все. Ну почти.
Да, это полная официальная адресная база России, просто в открытом доступе, никто ничего не спрашивает, просто раздают. Сделали на наши налоги, и честно всем, как скамейку в парке, отдают в пользование. Прекрасно? Да!
"В чем же подвох?", — спросите вы, прищурившись.
Кратко: формат ужасен, документация очень плоха и должного единообразия данных не наблюдается, чем успешно пользуются коммерческие компании, перепродающие бесплатные данные (иногда пылесосят имейлы). Но такую несправедливость можно исправить.
Что это за база и зачем ее парсить
ГАР — Государственный Адресный Реестр | БД — База Данных | ФИАС — Федеральная Информационная Адресная Система
Это полностью открытая и бесплатная база всех адресов нашей страны от ФНС России.
Как это всегда бывает, база в том виде, в котором она поставляется, может отличаться немного от региона к региону. Заполняются одни и те же поля тоже не обязательно в единой манере.
Всех проблем не перечислишь, казусов там много, выясняются они потом, во время эксплуатации, и скрипты обрастают хардкодом и гусями. Как правило, это отличие формальности от реальности. Из запоминающегося — Адлер, который вроде как формально — Адлерский район Сочи, но в реальности вроде как бы и нет.
В этой статье я вам сначала расскажу немного про ФИАС, его особенности и альтернативы, а кому сразу же хочется перейти к туториалу и коду — то колаб доступен по ссылке вместе с комментариями. Мы решили показать все на одном конкретном регионе (база структурирована по регионам) в Google Colab, который от Jupyter Notebook отличается номинально. Если у вас достаточно места на гугл диске, можно скачать более новую и полную базу напрямую на диск, там же разархивировать и радоваться. Учитывайте, что если архив базы весит 30 Гб, то в разархивированном виде, как это часто бывает с пережатыми текстами, ее раздувает в 10 раз, и она занимает уже все 300 Гб. В подтягивающемся репо есть небольшой, но достаточный для туториала, кусок ноябрьских данных. Скорее всего, на него вам места точно хватит. Дисклеймер: Я не гарантирую, что код будет работать для всех регионов и апдейтов. Я не гарантирую, что данный код способен распарсить все актуальные адресные цепочки из базы и не распарсит неактуальные. Не используйте этот код в проде, это просто туториал. Если что-то сделано менее эффективно, чем могло бы быть, и вам это не дает покоя, ваш вклад в репозиторий приветствеуется.
Мы используем ФИАС у себя в проде больше двух лет. Некоторое время назад ФИАС полностью перешел на формат ГАР, о чем они ранее предупреждали, и мы решили освежить свои скрипты, а заодно и прочувствовать по новой "красоту и единообразие" нашей адресной системы. Надо сказать, что она стала капельку лучше (но легче от этого стало незначительно). Так же мы изменили подход к сбору адресных цепочек и решили поделиться своим безудержным весельем со всеми желающими.
Нам удобно использовать датафреймы из пандаса и обычные питоновские словари. Первые легко агрегируются, но ужасно медленны при итерировании и доступу по ключам. Вторые безумно быстрые для доступа по ключу. Городить что-то более сложное, с хадупами, кубернетисами и модными ETL-инструментами, нам не нужно, такого набора достаточно для наших задач. Если же без этих ваших кубернетисов жить ну никак нельзя, то вы и сами сп��авитесь, не скромничайте.
Альтернативы
Ну есть OSM, бесплатный, да, не для всей России, не всегда актуален, держится на усилиях очень идейных людей, судя по всему. Названия там зачастую отличаются от официальных и порой встречаются сразу несколько вариантов одного и того же топонима. Поэтому несколько годен для сбора синонимов и разговорных названий. Выхлоп небольшой, но есть. По количеству усилий на очистку и слияние с официальной базой работать с ним куда более неприятно, чем с ФИАС. Но работать можно, и жаловаться грешно.
Из бесплатного, пожалуй, все. Если это не так — подскажите в комментах, будем благодарны.
Остальные базы платные, предоставляют доступ к API и обязательно ставят заградительные цены на всю базу (что абсолютно логично, кому нужны конкуренты?), либо прямо запрещают ее хранить и собирать. Там бывают бесплатные лимиты (например, до 10 000 запросов в сутки), или они требуют указывать, откуда вы получили данные, в своем приложении. Перечислять их смысла нет.
Есть компании, перепродающие ФИАС, иногда с дополнениями (DaData) или собирающие ваши данные (HFLabs). Несомненно, работа по очистке, поддержка, сбор координат из росреестра или другого источника, чего-то стоят, и кто-то не готов ее сам чистить и поддерживать, но готов заплатить, в том числе своими данными, и это нормально. Как относиться к тому, что в таком случае они не указывают первоисточник данных, где можно тупо скачать базу без вопросов, решайте сами.
Что там внутри ФИАС такого страшного
Вообще, правильнее с документации начинать в первую очередь (мы так и делаем), но если нет конкретной задачи, это превращается в муку. Всю структуру описывать не будем, тем более, что мы используем далеко не все возможное оттуда.
Важнее понять, как в целом подходить к ФИАС, и что она из себя представляет. Главный столп нашей адресной системы: Адресная система — это дерево, ветви (адресные цепочки) которого имеют разную длину и состав. Что это означает, объясню на примерах ниже.
Цепочки можно вытянуть из двух файлов, один с административным делением (историческим), другой с муниципальным (актуальным). Судя по моим изысканиям, отличия минимальные и затрагивают верхние уровни подчинения (административные и муниципальные районы).
Поэтому работаем с муниципальным делением. А вообще, чтобы помочь Даше отыскать все 10 различий, можно зайти сюда, выбрать деление и сравнить поля.
В лучших традициях ФИАС многие объекты "гуляют по уровням", например, всякого рода дачные и садовые территории могут считаться как улицей, так и элементом планировочной структуры, так и населенным пунктом. Все это делает приведение адресных цепочек к стандартному разговорному "населенный пункт, улица, дом" страшным геморроем. Вообще, то, как люди называют адреса в реальности может иметь мало общего с формальностью. Особенные названия микрорайонов, ЖК, топонимы из советского прошлого, — только малая часть того, что сразу приходит в голову.
У нас бывают улицы с одинаковыми названиями в одном городе в разных микрорайонах, бывают деревни и СНТ внутри городов, отсутствуют улицы в деревнях, бывают деревни-тезки в разных муниципальных районах, и прочие радости жизни. К счастью, цепочки от уровня здания теперь можно представить в едином виде с элементами от 10 до 1, где 10 — это дом, а 1 — регион, и подчиняются они именно в таком порядке.
А еще регион может быть населенным пунктом (города федерального значения, которые сами себе регион).
Иногда микрорайон или деревня, входящая в состав города, включается в название улицы в скобках, очень удобно (нет).
В некоторых регионах предусмотрительно выделена колонка PATH
с цепочкой адресов. Если же такой колонки там нет, то может помочь дополнительный ключ ОКТМО
, но ему тоже не на всех уровнях можно верить. В своих функциях я обращаюсь к сверке ОКТМО, когда вверху цепочки вдруг происходит взрыв. Почему так? А черт его знает, почему в Челябинской области весь славный город Челябинск в подчинении у собственных внутригородских районов. При попытке составить цепочки рекурсивно, в Челябинске одни и те же адреса оказываютя во всех районах одновременно. Но в Челябинске рекурсивно собирать цепочки не нужно, ведь есть колонка с цепочками, а вот в Дагестане ее нет. Почему бы не сделать и там отдельную колонку с цепочками? Я не знаю, работаем с тем, что имеем. Проверка ОКТМО не всегда спасает от транзитивных отношений, когда одно и то же здание попадает в несколько цепочек, так как верхние объекты подчиняются по транзитивной схеме. Для такого я просто проверяю, включаются ли более мелкие цепочки в более крупные, и если так, то мелкие цепочки оставляю за бортом.
Если обратиться к цифрам, то примерно вот так представлены адресные цепочки в России:
Чтобы использовать этот зоопарк на практике, мы пытаемся структурировать полученные цепочки таким образом: дом, улица, населенный пункт, остаток (leftover), муниципальный/административный район. Встает вопрос, вот допустим, есть город Мухосранск, в нем есть деревня Кочерыжкино, в деревне — улица Ватрушкина, на улице — дом 42. Что считать населенным пунктом при приведениии цепочки? Город или деревню? Зависит от того, где вы будете это применять и как. Мы обычно деревню определяем в остаток. Остаток может быть пустым. Муниципальный район редко используется, как правило, он нужен для различения одноименных городов и деревень-сателлитов.
Со зданиями (домами) все тоже зажигательно. Для номеров домов в ФИАС есть целых три колонки, видимо, чтобы уместить корпуса, строения, владения и прочие вынужденные отклонения от простоты и красоты. И три колонки для указания типа здания в довесок. И вот колонки есть, а как их заполнять, на местах все решили по-своему. Где-то все уместили в одну колонку вместе с литерами и корпусами. Где-то разнесли. Где-то одну и ту же информацию продублировали дважды или трижды во все колонки. Где-то вместо очевидного типа "Литера" подставлен другой неподходящий тип. Поэтому, собирая адресную ��троку, не стоит бездумно конкатенировать все три или шесть колонок и считать, что это настоящий номер дома. Придется разобрать все возможные виды извращенства и почистить вилкой.
Про документацию ФИАС надо заметить, что, во-первых, она есть, а во-вторых, она очень плохая. Как говорил мой препод в универе, без полбутылки не разберешься. Например, встречаются там поля ISACTUAL
и ISACTIVE
. Из документации не то чтобы понятно, в чем их назначение и различие. На практике оказывается, что этим полям не всегда можно верить. Бывало, еще в старом формате ФИАС, что вся Башкирия резко становилась устаревшей и неактивной, поэтому, банальные проверки на количество записей и размеры файлов после апдейтов будут нелишними. Любые предположения (а в случае плохой доки без них никак) в таких случаях нужно сначала попытаться проверить, и только потом применить.
Из менее раздражающих свойств ФИАСа можно заметить, что единые названия одних и тех же сущностей в разных таблицах не всегда практикуются, и в туториале можно наблюдать, как я переименовываю сразу колонки, чтобы не таскать за собой мусор из дублирующихся колонок с разным названием и одинаковым содержанием.
И что дальше
Публичные бесплатные данные — это прекрасно. И понятно, почему ФИАС такой всратый — потому что легаси, потому что унификация большой системы — это сложно, потому что всегда в подчинении оказываются немотивированные элементы, которые на все годные движухи хотели класть болта, потому что верхнее звено в субординации не откликается на зов подчиненных, и т.д. и т.п. Тем не менее, база становится все лучше, и однажды она наверняка станет замечательной, и может, координаты туда завезут из коробки, главное — пользуйтесь сами. Правильно ли кормить тех, кто протер скамейку в парке, првязал к ней бантик и просит теперь 10 рублей в час за нее? Так, глядишь, продадут народную скамейку, как Союзмультфильм продали.
Нужно, чтобы люди знали о существовании такой базы и пользовались ею. Чтобы люди понимали, что она бесплатная для всех, и даже вашу почту никто не спросит при скачивании. Расскажите об этом всем.
Теперь, когда у вас есть основные представления, остается лишь пройти по ссылке в колаб, и попробовать распарсить хотя бы один регион самостоятельно, разобравшись в коде.
На всякий случай кратенько опишу здесь, что в этом ноутбуке вообще происходит в каждом разделе:
- Установка зависимостей. Ну там все просто, может, придется рестартнуть райнтайм, если попросят.
- Монтируем гугл диск, клонируем репку, распаковываем данные из архива.
- Импортируем зависимости.
- Определяем утилиты. Это просто удобно — иметь все вспомогательные функции в одном месте. У них есть краткие описания. Например, все xml-файлы в ФИАС имеют похожую структуру, и конвертировать их в датафрейм можно одной из утилит.
- Основной раздел, работа на примере конкретного региона.
- Определяем регион.
- Читаем файл с адресными объектами. Попутно читаем и джойним все дополняющие файлы (типы и уровни объектов, параметры).
- Читаем файл со зданиями, в принципе, процесс особо не отличается, добавляются колонки для всяких корпусов и строений. Конкатенируем здания и адресные объекты в один датафрейм.
- Читаем файл с административным подчинением. Запоминаем, насколько нам повезло: есть ли колонка с готовыми адресными цепочками.
- Если повезло, парсим готовые цепочки. А если нет, то рекурсивно их строим сами. Основная магия в утилите
get_adms_rec_rev
. Чистим цепочки, если один объект попадает в несколько штук сразу. Создаем финальный фрейм с цепочками. Структурируем виды цепочек, джойним с финальным фреймом. - Сохраняем это все.
- Несколько независимая часть: после успешного прогона ячеек выше, рантайм можно перезапустить, и работать в данном разделе. Читаем наши результаты, преобразовываем адреса в плейнтекст и структурированный форматы, смотрим на то, что получилось.
Надеюсь, кому-то это окажется полезным. Ну а что делать с этим дальше, решать уже вам.