Как вычислить (город пользователя) по IP

    Зная местоположение человека, можно сделать тысячу полезных и не очень вещей: предложить правильный товар и заранее назвать цену доставки, показать ареал обитания покемонов, вывести локальные новости или посоветовать кафе неподалеку.

    Местоположение — это важно.



    Какие бывают способы геолокации


    Существует 2 базовых способа геолокации, если исключить парсинг геометок фотографий и шпионаж со спутников.

    Взять IP-адрес пользователя и по специальному справочнику найти город со страной.



    Узнать местонахождение через HTML5 Geolocation API.



    В этой статье мы рассказываем, как найти город пользователя, потому что такой точности обычно хватает. Го́рода достаточно интернет-магазинам, курьерским службам, новостным агрегаторам, сайтам с прогнозами погоды.

    Город лучше определять по IP: способ всегда работает и не тревожит пользователя. А в геолокации по IP главное — найти справочник, который удобно подключается и без ошибок выдает город. Вторая часть статьи — об этом.

    Как мы выбирали справочник IP-адресов


    В сравнении справочников есть большая проблема: невозможно проверить, действительно ли прямо сейчас IP-адрес принадлежит городу, найденному справочником. Вчера IP относился к Питеру, а сегодня это Нижний Новгород.

    Поэтому мы сравнивали справочники по таким критериям:

    1. Стоимость.
    2. Частота обновлений.
    3. Количество диапазонов IP-адресов для России.
    4. Количество адресов «на местности», или полнота. Чтобы измерить полноту, мы прогнали все адреса из каждого справочника через API cтандартизации «Дадаты». Сервис привел адреса к одному формату и разобрал по типам: регион, район, город. Эти стандартизованные адреса мы и посчитали.
    5. Формат: насколько справочник удобно использовать.
    6. Библиотеки и интеграции с популярными фреймворками.
    7. Что можно вытащить из базы помимо города.
    8. Чей Крым (политика политикой, а бизнесу работать надо).
    9. Детализация по населенным пунктам. Чтобы узнать ее, мы прогнали 35000 рандомных уникальных IP-адресов через каждый справочник. Потом сравнили, сколько уникальных городов разрезолвил каждый справочник.

    Мы рассматривали такие справочники:


    IPGeoBase


    Стоимость. Бесплатный.

    Обновления. Каждый день.

    Пулы IP-адресов в России. 43751 пул, это первое место.

    Полнота. 728 объектов:

    • 3 региона (Москва, Санкт-Петербург, Севастополь);
    • 2 района;
    • 601 город;
    • 113 прочих населенных пунктов.

    Третье место по этому параметру.

    Формат базы. Tab-separated текстовые файлы. В одном файле города с ID, в другом — залинкованные на них диапазоны IP.



    Кодировка в файлах — боль под названием Windows-1251. Хорошо, что есть iconv — легким движением руки мы получили UTF-8:

    iconv -f WINDOWS-1251 -t UTF-8 cities.txt > cities_utf8.txt 

    База медленная (еще бы, это текстовый файл) — обход 35000 адресов занял несколько минут.

    Библиотеки. Есть готовые под Perl, Ruby и Python, но самая новая — от 2013 года. За 4 года Трамп стал президентом США, вышел PHP 7, появился миллион JS-фреймворков, но ни одну из библиотек под этот справочник так и не обновили.

    Чтобы портировать библиотеку под Python 3, понадобился час.

    Что можно вытащить из базы.

    ('RU', 'Санкт-Петербург', 'Санкт-Петербург', ‘59.939037’, ‘30.315784’)

    Крым. Наш.

    Детализация. На выборке в 35000 адресов нашлось 372 разных населенных пункта.

    Это третье место с небольшим отставанием от второго.

    Вердикт. IPGeoBase — это набор городов и диапазонов IP-адресов, который завернут в .txt-файлы с tab-separated структурой. Обновляется достаточно часто.

    Минусы — библиотеки очаковских времен, да и текстовый файл — не самое удобное решение для доступа к данным.

    Повидавший жизнь, но до сих пор летающий Ту-154.



     

    SypexGEO


    Стоимость. Бесплатный, распространяется по BSD-лицензии.

    Обновления. Пару раз в месяц.

    Пулы IP-адресов в России. Всего диапазонов 1696337, но неясно, сколько из них относятся к России: данные закопаны в справочнике. По этому параметру место не присудить.

    Полнота. 832 объекта:

    • 2 региона,
    • 1 район,
    • 630 городов,
    • 196 прочих населенных пунктов.

    Второе место. Неплохо!

    Формат. Странный .dat-файл со структурой на смещениях. Внутренности быстро расковырять не получилось — создатель на форуме говорит, что конвертера для перевода базы в человекопонятный вид нет.

    Как работать со справочником, если не через библиотеку — неясно. Для любопытных есть спецификация на сайте справочника.

    Скорость хорошая: обход 35000 адресов занял несколько секунд.

    Библиотеки. Есть для Python, PHP Yii, PHP Laravel, Java, Ruby. Обновлялись 2-3 года назад. Еще есть интеграция с Symfony и плагин для Wordpress.

    Что можно вытащить из базы:

    {'city': 
        {'id': 498817, 
         'lat': 59.93863, 
         'lon': 30.31413, 
         'name_ru': 'Санкт-Петербург', 
         'name_en': 'Saint Petersburg'}, 
    'region': 
        {'id': 536203, 
        'name_ru': 'Санкт-Петербург', 
        'name_en': 'Sankt-Peterburg', 
        'iso': 'RU-SPE'}, 
    'country': 
        {'id': 185, 
        'iso': 'RU', 
        'lat': 60.0, 
        'lon': 100.0, 
        'name_ru': 'Россия', 
        'name_en': 'Russia'}, 
    'region': 'Санкт-Петербург', 
    'tz': ''"}

    Крым. Не наш.

    Детализация. На выборке в 35000 адресов нашлось 400 разных населенных пунктов.

    Это второе место.

    Вердикт. Очень подкупает скоростью, смещения — сила. Авторы говорят, что специально оптимизировали базу для высоких нагрузок.

    По наполнению и точности похожа на IPGeoBase — здесь чуть больше объектов, 10% адресов резолвятся по-другому.

    База полностью открыта.

    К сожалению, не резолвит Крым в Россию.

    Вертолет Black Hawk — классно летает, но не всем подойдет.



     

    MaxMind Lite


    Стоимость. Бесплатный с лицензией Creative Commons. Есть платная версия, которая стоит $1470 в год.

    Обновления. Первый вторник каждого месяца (прям как паспортный стол).

    Пулы IP-адресов в России. 91432. Если убрать IP-адреса, которые резолвятся в Россию без города, — 42822. Это второе место.

    Полнота. 1392 объекта:
     
    • 61 регион,
    • 819 городов,
    • 497 населенных пунктов.

    Первое место с большим отрывом!

    Формат базы. Собственный .mmdb. Города и диапазоны IP-адресов доступны также в .csv-файлах, которые лежат в архиве с базой.

    У базы есть версии с разной точностью: до страны, до города, а также справочник ASN (уникальных номеров интернет-провайдеров). Есть также база для IPv6-адресов.

    Библиотеки. Здесь полный порядок — на «Гитхабе» лежит несколько десятков библиотек для работы с базой.

    Что можно вытащить из базы. Выдача суперподробная и мультиязычная. MaxMind отдает интересный параметр accuracy_radius — точность радиуса координат в километрах.

    {
      "city": {
        "geoname_id": 498817,
        "names": {
          "de": "Sankt Petersburg",
          "en": "Saint Petersburg",
          "es": "San Petersburgo",
          "fr": "Saint-Pétersbourg",
          "ja": "サンクトペテルブルク",
          "pt-BR": "São Petersburgo",
          "ru": "Санкт-Петербург",
          "zh-CN": "圣彼得堡"
        }
      },
      "continent": {
        "code": "EU",
        "geoname_id": 6255148,
        "names": {
          "de": "Europa",
          "en": "Europe",
          "es": "Europa",
          "fr": "Europe",
          "ja": "ヨーロッパ",
          "pt-BR": "Europa",
          "ru": "Европа",
          "zh-CN": "欧洲"
        }
      },
      "country": {
        "geoname_id": 2017370,
        "iso_code": "RU",
        "names": {
          "de": "Russland",
          "en": "Russia",
          "es": "Rusia",
          "fr": "Russie",
          "ja": "ロシア",
          "pt-BR": "Rússia",
          "ru": "Россия",
          "zh-CN": "俄罗斯"
        }
      },
      "location": {
        "accuracy_radius": 20,
        "latitude": 59.9321,
        "longitude": 30.1968,
        "time_zone": "Europe/Moscow"
      },
      "postal": {
        "code": "191023"
      },
      "registered_country": {
        "geoname_id": 2017370,
        "iso_code": "RU",
        "names": {
          "de": "Russland",
          "en": "Russia",
          "es": "Rusia",
          "fr": "Russie",
          "ja": "ロシア",
          "pt-BR": "Rússia",
          "ru": "Россия",
          "zh-CN": "俄罗斯"
        }
      },
      "subdivisions": [
        {
          "geoname_id": 536203,
          "iso_code": "SPE",
          "names": {
            "en": "St.-Petersburg",
            "es": "San Petersburgo",
            "fr": "Léningrad",
            "ru": "Санкт-Петербург"
          }
        }
      ],
      "traits": {
        "ip_address": "109.205.249.212"
      }
    }

    Крым. Не наш.

    Детализация. На выборке в 35000 адресов справочник нашел 749 адресных объектов.

    Это первое место.

    Но есть нюансы:

    • в 13% случаев база не сумела определить город. Поняла только, что он находится в РФ, и разрезолвила страну;
    • создатели намекают, что определение адреса по IP — не самая сильная сторона бесплатной версии. Для контроля точности они предлагают мониторить accuracy_radius.

    Вердикт. Подробнейшая база с шикарной выдачей.

    В 50% случаев результаты расходятся с предыдущими двумя базами — точность и детализация у MaxMind Lite выше.

    Но есть принципиальные минусы — частота обновлений и Крым.

    Навороченный космический корабль, который обновляется раз в месяц и не считает Крым российским.



     

    ip2ruscity


    Стоимость. Платный, стоит 5000 рублей в год.

    Обновления. Раз в месяц.

    Пулы IP-адресов в России. 34907 пул, третье место.

    Полнота. 486 объектов:

    • 4 региона,
    • 454 города,
    • 28 населенных пунктов.

    Четвертое место, которое сильно слабее третьего.

    Формат базы. Tab-separated текстовые файлы либо SQL-файлы. В них — города, регионы, диапазоны IP-адресов. Есть еще телефонные коды городов, но почему-то они доступны только в MySQL-формате. В общем, как в программе партии «Неуверенная Россия» — будет средне (не прямо круто, так, нормально).

    Начало и конец диапазонов IP-адресов для экономии места завернуты в uint-формат. Их придется самостоятельно привести к виду IP-адресов.



    Не особо удобно, но жить можно. На Python делается просто:

    import socket, struct
    socket.inet_ntoa(struct.pack('!I', 84098303))
    '5.3.60.255'

    Библиотеки. Не нашлось ни одной :(. Пришлось накостылить свой авангардный биндинг для исследования, код публиковать не буду.

    У сервиса недавно появилось API. Через него отдают:

    • город,
    • регион,
    • координаты по Google Maps и «Яндекс.Картам».

    API относительно бесплатное — не больше 20 запросов в сутки с одного IP-адреса. В платной версии дают 3000 запросов в час.

    Что можно вытащить из базы.

    {'city': 'Санкт-Петербург',
    'region': 'Санкт-Петербург',
    'region_id': '78'}

    Если использовать MySQL-формат базы, возвращается еще телефонный код города.

    Крым. Наш.

    Детализация. На выборке в 35000 адресов нашлось 273 населенных пункта. Это последнее место.

    Вердикт. Вроде и недорого, но за деньги могло быть и получше.

    Винтовой ATR-72 авиакомпании Air Serbia.



     

    Подводя итоги (как первый канал)


    Бесплатная MaxMind Lite практически по всем параметрам быстрее, выше и сильнее остальных. Тем не менее, у нее 2 важных минуса — обновляется всего раз в месяц и не считает Крым российским.

    Мы в «Дадате» не спали ночами и думали, какой справочник выбрать для своего API геолокации. В итоге взяли за основу IPGeoBase и навернули сверху всяких плюсов.

    По сравнению с «голым» IPGeoBase «Дадата» удобнее.

    Обновляется автоматически. Сервис обновляет справочник по мере выхода новой версии, вспоминать об этом не придется.

    Библиотеки не нужны. Справочник доступен по API, к нему подключится любая HTTP-библиотека. Запрос очень простой: отправляешь только IP-адрес и токен, который дают при регистрации на DaData.ru.

    curl -X GET \
      -H "Accept: application/json" \
      -H "Authorization: Token ${yoursecrettoken}" \
    https://suggestions.dadata.ru/suggestions/api/4_1/rs/detectAddressByIp?ip=213.180.193.3
    

    Сервис отдает куда больше данных, чем «голый» справочник. Помимо названия найденного объекта это:

    • детализация, до которой удалось разрезолвить IP: страна, регион, район, город, населенный пункт;
    • типы и названия найденного и всех вышестоящих адресных объектов (например, города → района → региона → страны);
    • коды КЛАДР и ФИАС для найденного и всех вышестоящих адресных объектов (региона, района и  т. д.);
    • признак центра района, региона, района и региона;
    • коды ИФНС, ОКАТО и ОКТМО.

    Всего в выдаче для IP несколько десятков полей, на DaData.ru есть полная спецификация.

    Мы превратили рабочий, но некрашеный Ту-154 в Airbus А-380.

    В экономе возим бесплатно — к API можно сделать 10000 запросов в сутки, просто зарегистрировавшись. Если нужно больше, это будет стоить от 4000 рублей в год.

    HFLabs 36,88
    Качество и интеграция клиентских данных
    Поделиться публикацией
    Комментарии 38
    • +4
      Есть достаточно хороший сервис freegeoip.net/json, который не требует токен, и может отдавать в разных форматах
      • +1
        Да, интересный проект, на Go и в Докере. Интересно, какую базу они используют как основу?
      • 0

        Пользуемся несколько месяцев. Пока страну угадывает корректно.

      • 0
        Живу в Щелково, провайдер из Ногинска, все сайты думают, что я из Клина.

        ps. HTML5 Geolocation API раньше(летом проверял) показывал на десктопе точность до дома(в гугл и яндекс картах, как минимум), меня это напрягало, поэтому запретил везде, где только можно. Теперь(вот только что проверил), HTML5 Geolocation API показывает дом в Рязани, где я жил в 2012 году, и у меня тогда был другой ноут, и другой адрес gmail, и почты на Яндексе вообще не было… вот ща реально стремно стало.
        • 0
          Можно Ваш IP?
          Поискать, сможет ли кто-то правильно определить.
          Сайт ВКонтакте правильно определяет?
          • 0

            Проводной Билайн (бывшая Корбина) в Москве иногда выдает IP из Санкт-Петербуржского пула. А может у них вовсе единый пул для Москвы/области и Санкт-Петербурга. Заходишь в Яндекс.Карты, а тебе вдруг, внезапно, карту Санкт-Петербурга показывают :) Пришлось в настройках Яндекса регион вручную указать

            • 0

              Аналогично. Живу в Краснодаре, сервисы регулярно то в Ростов, то в Воронеж, то в Москву кидают.
              Поставил в Хром дополнение Manual Geolocation — теперь все путем.

          • 0
            Трекинг пользователей и последующее сопоставление данных о них — это отдельная веселая история, которую, к сожалению, никто не расскажет :)
            • 0
              А роутер тот же?
              • 0
                Я так понимаю, IP статический (или просто сессия на роутере висит днями и неделями), и через домашнюю сеть также использовались мобильные устройства с WiFi и GPS?
                • 0
                  Ситуация почти наоборот. Я из Клина, местный провайдер работает через провайдера из Ногинска, все сайты думают, что я из Ногинска.
                • 0
                  У 2ip.ru тоже своя база есть, которая ежедневно обновляется, апи есть, ключ в акаунте можно взять.
                  • 0
                    2ip меня только что послала в Францию, и это при статическом ип, прикольно конечно. но точность…
                    • 0
                      У 2IP база настолько древняя, что к примеру сеть моего провайдера, которой мы пользуемся уже лет 5 до сих пор числится со старыми данным.В whois корректно указаны lat/lon, country:, как у AS в которую она входит. Аналогично с контактами maintainer-ов. Более крупные inetnum-ы в whois отсутствуют.
                      Судя по всему, эта проблема растёт из того, что следующая /23 действительно относится к этому некорректному региону.
                    • 0
                      сделайте страничку на которой будут отрабатываться запросы к разным бд, сравнивать было бы прикольно
                        • 0
                          спасибо :) поржал.
                          все предположили что я в москве, хотя до нее с полтыщи километров :)
                          но сильно выделился DB-IP (Product: Full, 2017-10-1)
                          он определил Russia,Republic of Tyva, Kyzyl (51.7167, 94.45)
                          я *** дорогая редакция, вроде б город не закрывали, не секретили…
                      • +1
                        Пробовали MaxMind для интернет магазина в России. Очень плохо определяет города в Московском регионе и в общем плохо по всей стране. В Кирове пробовали с разных мест/провайдеров определить город — ни один не распознало.

                        Для России пользуемся ipgeobase, определяет город несопоставимо лучше.
                        • НЛО прилетело и опубликовало эту надпись здесь
                          • +1
                            Да, в Европе с этим весело :) Меня находит в трех соседних странах периодически.
                          • 0
                            Есть еще одна проблема, относящаяся к мобильным операторам: у них чаще всего адресация идет по региону привязки сим-карты, соотвественно, информация о геолокации IP-адреса может не соответствовать действительности. У Yota, если мне не изменяет память, все сим-карты адресуются через Москву, а МТС часто редиректит в соседний регион.

                            По поводу Крыма: там, судя по всему, магистральный трафик местных операторов закупается с «материка» Украины? По этому критерию сервисы и отсеивают регион (e.g. App Store, Steam)? Если так, то оптоволокно с другого «материка» проблему, вероятнее всего, решит.
                            • 0
                              Пытался как-то зарегистрировать региональное интернет сми. Смысл в том что доступ только для жителей региона/города. Технической мерой обеспечения исполнения закона — что доступ будет только у жителей региона было указание на то, что к материалам доступ будет только у региональных ip адресов (по geoip базе)
                              Судья городского суда решил что это невозможно и отказал в удовлетворении иска к управлению Роскомнадзора на отказ в регистрации регионального интернет сми. Такие дела.
                              • +1

                                Если нужно определять по России, DaData, собственно и использую. Если нужны города по всему миру, то SxGeo. Проблему Крыма/Севастополя решить достаточно просто. Там административное деление не поменялось, как было две единицы "город Севастополь" и "Республика Крым", так и остались. В массиве, который отдает sxGeo при вызове getCityFull можно ISO-код региона проверять и корректировать значение в зависимости от предпочтений. Можно даже настройку в продукте сделать "чей Крым" :)

                                • +1
                                  После года использования wifi-роутера отвез его из Питера родителям в другую область. Когда приезжал к ним (примерно в течение года) на ноуте все сервисы считали что я нахожусь в Питере. Кроме гуглокарт, которые хитрые и пытаются сначала получить информацию с GPS рядом лежащего телефона, а потом показать в аккаунте. Когда не получается найти GPS — показывают Питер.
                                  Насколько я слышал (гуглить пруфы лень) — Google ведет свою базу wifi-сетей, по которым сам отслеживает пользователей и может эту информацию предоставлять сервисам.
                                  • +1
                                    У себя в проекте использую одновременно оба справочника — ipgeobase и maxmind. Для тех адресов, что есть в первом — резольвится город из первого справочника, если не отрезольвился — то из второго. Неудобство только в том, что в ipgeobase файл текстовый, но это проблему решил конвертацией файла при обновлении базы в B-дерево.
                                    • 0
                                      Вот что-то мне подсказывает, что именно текстовый вид данных от такого поставщика оптимален. Не надо зависеть от каких-то библиотек. Можно легко распарсить и переписать в подходящий для себя формат какую бы платформу/БД/… не использовали. Опять же, можно интегрировать с какими-то своими данными.
                                      Так что такой формат, на мой взгляд, не минус — а большой плюс.
                                      • 0
                                        Такой формат сильно бьет по скорости работы с базой, как и конвертация в обычную БД.
                                        • 0
                                          Конвертацию нужно выполнять только при обновлении базы.
                                          • 0
                                            Да, но ведь дело не в конвертации. Проблема в том, что просто БД на большой нагрузке – это тупо медленно :) И желательно иметь человека, который ее правильно приготовит.
                                            Здесь MaxMind и SypexGeo имеют свои форматы баз, которые на нагрузке быстрее, чем «а давайте зальем csv в Postgres, у нас же хайлоад». А Дадата вообще убирает нагрузку с сервера и базы.
                                    • –1
                                      Спасибо SypexGEO и MaxMind Lite за непособничество оккупантам.
                                      • 0
                                        Интересно, АПИ Яндекса по какой базе работает?
                                        • +1
                                          Думаю, что Яндекс свою базу собирает, во всяком случае по РФ.
                                        • 0
                                          Платный MaxMind вне конкуренции. Но лучше всего оказалось совмещать его с броузерным АПИ получения местоположения.
                                          И не соглашусь с автором статьи, неоспоримым преимуществом MaxMind является то, что

                                          Крым. Наш.
                                          • –1
                                            хорошая мантра, но объективная реальность другая. Поэтому MaxMind действительно — вне конкуренции, но Крым де-факто принадлежит России, и всегда можно(приходится) подменять страну при адресах из Крыма.
                                            • –1
                                              А как вы это понимаете, что он вне конкуренции?
                                            • 0
                                              используя Яндекс локатор.

                                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                              Самое читаемое