Как мы создали парсер баз данных провайдеров, а в итоге он стал находить ошибки самих провайдеров

Все счастливые семьи похожи, предлагает мне vc.ru. Ну а я скажу о том, что это мой самый любимый кейс, и сегодня хочу рассказать: что мы хотели сделать, для чего это нам было нужно, и с какими проблемами мы столкнулись.

Краткая предыстория

Первое, с чего бы хотелось начать - а зачем нам нужен был парсер адресных баз интернет-провайдеров? Это не сложно. Мои друзья заключили партнерки с компаниями Ростелеком, Билайн, МТС и похожими ребятами. Они собирали заявки на подключение, а провайдерам передавали уже готовых к подключению клиентов. Когда я присоединился к проекту моих друзей, у них были несколько лендингов по Москве на разных провайдеров и вера в то, что в этой нише можно неплохо заработать. Я переверстал лендинги, объединил их в единую систему так, чтобы весь контент можно было заменять из админ-панели за 2 минуты, а создание нового лендинга на поддомене занимало 5 минут. Мы росли, и всё было замечательно, но на протяжении лет было 3 основные проблемы:

  • высокая конкуренция за рекламное место в поисковиках
  • склейка нашего сайта с сайтами конкурентов
  • большие временные затраты на ручную проверку возможности подключения абонента

Проблематика

Итак, решением первых двух проблем стала прокачка SEO, но переиграть агрегаторы вроде 101internet.ru, имея на руках пусть даже 100 лендингов - задача как минимум непростая. Склейка происходила, чаще всего, по двум причинам: первая - один из конкурентов жаловался ребятам из Яндекса, что мы пустили в рекламу копию их сайта, а вторая - контент на всех сайтах, предлагающих услуги провайдеров, был до неприличия похожим. Последнее происходило (а возможно происходит и сейчас) из-за того, что правила рекламирования тарифов были одни для всех. Я не могу сказать, что это однозначно плохо, у каждой компании провайдера есть свои причины выдвигать те или иные условия сотрудничества. Наш выбор заключался в том, чтобы соглашаться с ними и работать, или отказываться их принимать и упустить долю рынка.

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

Вы спросите, а что же с третьей проблемой? На самом деле, мы не думали о ней до тех пор, пока косвенно её не решили. Причиной тому была простая человеческая привычка. Менеджеры по продажам привыкли работать по Excel-таблицам с адресами, которые нам предоставляли провайдеры. Да, они не самые удобные, да, они все разные, да, надо было научиться ими пользоваться, но под них уже были выстроены и отлажены несколько бизнес-процессов, которые несколько лет подряд работали как часы. Смысл агрегаторов - удобный поиск продуктов, информация по которым заботливо собрана и обработана до вас. Если немного потренироваться в подмене понятий, то маркетплейсы - это тоже своего рода агрегаторы.

Так вот, смысл до нас дошел только в процессе разработки.

Раз уж мы даём возможность нашим пользователям легко находить нужные адреса и тарифы, почему бы нам не дать эту возможность нашим продажникам?

Голос в голове

Интернет Киоск. Уникальность

Как мы создали парсер баз данных провайдеров, а в итоге он стал находить ошибки самих провайдеров

В чем же, в чем же уникальность нашего сервиса? А ни в чем, по большей части. Мы смотрели на конкурентов и видели, где могли сделать лучше. Основным параметром качественного отличия была точность нашей адресной базы. Конечно, мы много сделали по дизайну, архитектуре приложения, решили несколько UI-моментов (например, у 101интернет поиск по адресу состоит из двух абсолютно, как по мне, раздражающих полей). Тем не менее, мы стремились к тому, чтобы любой существующий в России адрес, при условии, что по нему есть подключение хотя бы у одного провайдера, пользователь мог бы его найти по привычной формулировке. Другими словами, в нашем сервисе ни в коем случае не должно произойти такой ситуации, когда пользователь вынужден вводить свой адрес по частям, вплоть до района, удела, почтового индекса, площади туалета и кадастрового номера помещения

Работа с адресами

Естественно, нам понадобился парсер. Парень, который бы собрал все адреса из Excel-табличек, стандартизировал их и положил в базу. Звучит как будто бы несложно. Ни хре на. Даже с учетом того, что мы не стали разрабатывать свой API для работы с адресами или скачивать базы ФИАС/КЛАДР (в 2021 году это можно было сделать, базы весили по 5-10 ГБ на регион), парсер должен был содержать в себе несколько важных и не самых очевидных подсистем. Но прежде, чем мы начнём, хочу упомянуть о сервисе, который облегчил нам работу с адресами, как в клиентской части, так и в парсере - dadata.ru

Почему мы не выбрали Яндекс Карты? У них до ужаса дорогой API. Хоть он и точнее, и удобнее, для нас в тот момент эта дороговизна была бы губительной.

Вернёмся к парсеру.

Проверка и добавление адреса в базу

Здесь всё более-менее просто. У нас было основное тело парсера, который работал с API dadata, проверял, насколько получается точный результат, и помещал результат в базу. И были подмодули, которые отвечали за первоначальную обработку адресов из таблиц провайдеров. Все провайдеры использовали свой формат, удобный для них самих - стандартная практика. Нам нужно было это превратить во что-то, что можно было бы скормить в dadata и получить адекватный ответ. Этот процесс запускался всегда, когда парсер понимал, что перед ним - неизвестный адрес. Почему так? Ну, хотя бы потому что за использование API Стандартизация сервиса dadata нужно платить денежку :) Поэтому мы не могли себе позволить запускать эту проверку на каждый чих, пришлось использовать свой мозг.

Обновление адреса

Так что же это значило для нас - использовать свой мозг? Возьмём случай, когда мы повторно загружаем таблицу с базой адресов в базу. Мы могли бы обратиться к dadata API, стандартизировать полученный адрес, и по этому адресу обратиться к базе.

Когда это может случиться? Например, по адресу сменилась технология подключения. Она напрямую влияет на максимальную скорость передачи данных. Вместо того, чтобы каждый раз обращаться к API, мы решили сохранять входной адрес в базе, чтобы всегда была возможность по входному адресу найти запись у себя.

Зачем так? Провайдеры в среднем обновляли адресные таблицы раз в 1-2 месяца. Количество записей в одной таблице от 10 000 до 30 000, в зависимости от провайдера (это только в Москве). За каждое такое обновление меняется от 10 до 20 адресов. На данный момент каждый запрос стоит около 15 копеек. Я думаю, не нужно пояснять разницу между 4 500 рублей и 3 рубля. Особенно, если посчитать на дистанции в год.

Удаление адреса

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

Провайдеры могут отключать адрес от интернета и подключать его обратно

Голос гипотез

Что же из этого следует? Всё очень просто. Если мы просто удалим запись, нам придётся стандартизировать старый адрес по-новой, если провайдер решит вернуть подключение к адресу. Поэтому удаление у нас стирало не саму запись, а лишь упоминание о том, что там присутствует такой-то провайдер. При этом все исходные данные и результаты обработки dadata API оставались в базе.

Как будто бы и всё, мы рассмотрели все основные операции с базой данных, за исключением чтения, к которому ещё вернёмся чуть позже. Мы делали проект в тот год, когда модели ИИ только-только набирали обороты. Их разработка и обучение было долгим и дорогим мероприятием.

Если ближе к делу, конвенциональный алгоритм мог самостоятельно обработать около 99,8% адресов за счёт выкрученных в около максимум параметров точности определения адреса. Мало!

Сохранение и обработка некорректных адресов

Да, мы не обошлись без помощи людей. Единственное, что мы могли сделать - упростить процесс проверки некорректного адреса и превратить процесс в конвейер. Как в середине 2010-х я заполнял интернет-магазины септических систем товарами, так наши продажники проверяли адреса, которые не смог обработать парсер. Разве что, под впечатлением своего опыта, я сделал всё, чтобы процесс проверки был простым и быстрым. Под это даже была отдельная инструкция, которая читается гораздо легче, когда перед глазами есть интерфейс.

Что было в интерфейсе. Мы сделали визуальное отображение dadata API для сотрудников, кто занимался проверкой некорректных адресов. Кто-то скажет, чел, у тебя 99,8% обработались правильно, это же похоже на успех. Проблема в цифрах: 0,02% от 75 000 адресов (напоминаю, это только Москва) = 1500 адресов, по которым люди не смогут найти себя. Это много. Я рос в посёлке, в котором было 3000 человек. Представьте, половина из них в теории не могла бы воспользоваться сервисом.

К концу проверки у нас осталось порядка 10 некорректных адресов. Это были те адреса, которые не могут существовать в Москве. После отправки запроса к провайдерам мы получили ответ: это мусорные адреса, когда-нибудь мы их удалим. Такой расклад нас устроил. Картина не получилась идеальной (как будто бы она должна такой быть), тем не менее, это были те показатели, с которыми мы готовы были работать. И вроде бы всё, можно расслабиться, но остаётся ещё одна вещь, которая не даёт нам спокойно жить.

Палки в колёса

Есть такой тип данных, очень удобный, когда заходит речь о хранении геоданных, называется GeoJSON. Вы сохраняете геометку - координаты - по определённому формату и обращаетесь к нему по необходимости. Такой запрос работает быстрее, чем если бы вы искали его по двум полям: широта и долгота. Это не говоря уже о поиске адреса по его полной формулировке. Но у нас не вышло. Почему? Во-первых, ограничения сервиса dadata, во-вторых, экономика проекта, мы же не использовали API Яндекс Карт. В чем же соль? На протяжении всей статьи я рассказывал, как нам помогает сервис dadata. Но тут он сыграл с нами, скажем, смешную шутку.

На стороне клиента для определения адреса мы использовали сервис dadata Подсказки. Это давало нам возможность валидировать введённый пользователем адрес. В чём же соль? Координаты объектов в сервисах Стандартизация и Подсказки были разные! Другими словами, использовать классный новый для нас тип данных мы попросту не могли. Нам оставалось только выкручиваться - сделать поиск по полному совпадению адреса с минимальными изменениями (введённый с клиента адрес мы немного переформатировали и отправляли запросом в базу данных). Было ли это приятно? Да какая разница. Это была наша работа - сделать, чтобы работало. И работало это хорошо.

Заключение

Завоевать рынок Киоску было не суждено. Мы либо не попали в нужное время, либо разрабатывали его слишком долго. Я точно знаю, что он был достаточно хорош, чтобы это сделать. А ещё, что мы при его реализации научились думать головой и шевелить мозгами быстрее.

В каждом проекте бывают свои подводные камни, важно не столько знать о них заранее, сколько понимать, как с ними нужно работать. Это понимание чаще всего приходит с опытом, который у меня присутствует. Вам нужно зарешать эти подводные камни или не знаете, с чего начать работу над своим проектом - я обитаю тут @pboloshov и тут @boloshov_projects. Обращайтесь, буду рад пообщаться и помочь

Спасибо)

44
3 комментария

Необычный кейс и написано хорошо, неожиданно конечно, что столько тонкостей и нюансов за подобной задачей стоит. Интересно узнать, у вас специализация именно на подобных задачах или вы можете помочь, допустим, с AI, онлайн-сервисами, интернет-магазинами и т.д.?

Автору лайк однозначно)

Ответить

Спасибо)
В основном я занимаюсь веб-сервисами в широком понимании слова. Онлайн-сервисы, интернет-магазины, корпоративные сайты - это лишь малая часть того, с чем я работаю. Единственное, пока до AI не добрался. Но это пока)

1
Ответить

Жаль, что "завоевать рынок Киоску было не суждено". Проект вышел интересный. Ну хоть руку набили.

Ответить