- PVSM.RU - https://www.pvsm.ru -
Зная местоположение человека, можно сделать тысячу полезных и не очень вещей: предложить правильный товар и заранее назвать цену доставки [1], показать ареал обитания покемонов, вывести локальные новости или посоветовать кафе неподалеку.
Местоположение — это важно.

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

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

В этой статье мы рассказываем, как найти город пользователя, потому что такой точности обычно хватает. Го́рода достаточно интернет-магазинам, курьерским службам, новостным агрегаторам, сайтам с прогнозами погоды.
Город лучше определять по IP: способ всегда работает и не тревожит пользователя. А в геолокации по IP главное — найти справочник, который удобно подключается и без ошибок выдает город. Вторая часть статьи — об этом.
В сравнении справочников есть большая проблема: невозможно проверить, действительно ли прямо сейчас IP-адрес принадлежит городу, найденному справочником. Вчера IP относился к Питеру, а сегодня это Нижний Новгород.
Поэтому мы сравнивали справочники по таким критериям:
Мы рассматривали такие справочники:
Стоимость. Бесплатный.
Обновления. Каждый день.
Пулы IP-адресов в России. 43751 пул, это первое место.
Полнота. 728 объектов:
Третье место по этому параметру.
Формат базы. Tab-separated текстовые файлы. В одном файле города с ID, в другом — залинкованные на них диапазоны IP.

Кодировка в файлах — боль под названием Windows-1251. Хорошо, что есть iconv — легким движением руки мы получили UTF-8:
iconv -f WINDOWS-1251 -t UTF-8 cities.txt > cities_utf8.txt
База медленная (еще бы, это текстовый файл) — обход 35000 адресов занял несколько минут.
Библиотеки. Есть готовые под Perl [7], Ruby [8] и Python [9], но самая новая — от 2013 года. За 4 года Трамп стал президентом США, вышел PHP 7, появился миллион JS-фреймворков, но ни одну из библиотек под этот справочник так и не обновили.
Чтобы портировать библиотеку под Python 3, понадобился час.
Что можно вытащить из базы.
('RU', 'Санкт-Петербург', 'Санкт-Петербург', ‘59.939037’, ‘30.315784’)
Крым. Наш.
Детализация. На выборке в 35000 адресов нашлось 372 разных населенных пункта.
Это третье место с небольшим отставанием от второго.
Вердикт. IPGeoBase — это набор городов и диапазонов IP-адресов, который завернут в .txt-файлы с tab-separated структурой. Обновляется достаточно часто.
Минусы — библиотеки очаковских времен, да и текстовый файл — не самое удобное решение для доступа к данным.
Повидавший жизнь, но до сих пор летающий Ту-154.

Стоимость. Бесплатный, распространяется по BSD-лицензии.
Обновления. Пару раз в месяц.
Пулы IP-адресов в России. Всего диапазонов 1696337, но неясно, сколько из них относятся к России: данные закопаны в справочнике. По этому параметру место не присудить.
Полнота. 832 объекта:
Второе место. Неплохо!
Формат. Странный .dat-файл со структурой на смещениях. Внутренности быстро расковырять не получилось — создатель на форуме говорит, что конвертера для перевода базы в человекопонятный вид нет.
Как работать со справочником, если не через библиотеку — неясно. Для любопытных есть спецификация на сайте справочника [10].
Скорость хорошая: обход 35000 адресов занял несколько секунд.
Библиотеки. Есть для Python [11], PHP Yii [12], PHP Laravel [13], Java [14], Ruby [15]. Обновлялись 2-3 года назад. Еще есть интеграция с Symfony [16] и плагин для WordPress [17].
Что можно вытащить из базы:
{'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 — классно летает, но не всем подойдет.

Стоимость. Бесплатный с лицензией Creative Commons. Есть платная версия, которая стоит $1470 в год.
Обновления. Первый вторник каждого месяца (прям как паспортный стол).
Пулы IP-адресов в России. 91432. Если убрать IP-адреса, которые резолвятся в Россию без города, — 42822. Это второе место.
Полнота. 1392 объекта:
Первое место с большим отрывом!
Формат базы. Собственный .mmdb. Города и диапазоны IP-адресов доступны также в .csv-файлах, которые лежат в архиве с базой.
У базы есть версии с разной точностью: до страны, до города, а также справочник ASN (уникальных номеров интернет-провайдеров). Есть также база для IPv6-адресов.
Библиотеки. Здесь полный порядок — на «Гитхабе» лежит несколько десятков [18] библиотек для работы с базой.
Что можно вытащить из базы. Выдача суперподробная и мультиязычная. 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 адресных объектов.
Это первое место.
Но есть нюансы:
Вердикт. Подробнейшая база с шикарной выдачей.
В 50% случаев результаты расходятся с предыдущими двумя базами — точность и детализация у MaxMind Lite выше.
Но есть принципиальные минусы — частота обновлений и Крым.
Навороченный космический корабль, который обновляется раз в месяц и не считает Крым российским.

Стоимость. Платный, стоит 5000 рублей в год.
Обновления. Раз в месяц.
Пулы IP-адресов в России. 34907 пул, третье место.
Полнота. 486 объектов:
Четвертое место, которое сильно слабее третьего.
Формат базы. Tab-separated текстовые файлы либо SQL-файлы. В них — города, регионы, диапазоны IP-адресов. Есть еще телефонные коды городов, но почему-то они доступны только в MySQL-формате. В общем, как в программе партии «Неуверенная Россия» — будет средне (не прямо круто, так, нормально).
Начало и конец диапазонов IP-адресов для экономии места завернуты в uint-формат. Их придется самостоятельно привести к виду IP-адресов.

Не особо удобно, но жить можно. На Python делается просто:
import socket, struct
socket.inet_ntoa(struct.pack('!I', 84098303))
'5.3.60.255'
Библиотеки. Не нашлось ни одной :(. Пришлось накостылить свой авангардный биндинг для исследования, код публиковать не буду.
У сервиса недавно появилось API. Через него отдают:
API относительно бесплатное — не больше 20 запросов в сутки с одного IP-адреса. В платной версии дают 3000 запросов в час.
Что можно вытащить из базы.
{'city': 'Санкт-Петербург',
'region': 'Санкт-Петербург',
'region_id': '78'}
Если использовать MySQL-формат базы, возвращается еще телефонный код города.
Крым. Наш.
Детализация. На выборке в 35000 адресов нашлось 273 населенных пункта. Это последнее место.
Вердикт. Вроде и недорого, но за деньги могло быть и получше.
Винтовой ATR-72 авиакомпании Air Serbia.

Бесплатная MaxMind Lite практически по всем параметрам быстрее, выше и сильнее остальных. Тем не менее, у нее 2 важных минуса — обновляется всего раз в месяц и не считает Крым российским.
Мы в «Дадате» не спали ночами и думали, какой справочник выбрать для своего API геолокации [19]. В итоге взяли за основу IPGeoBase и навернули сверху всяких плюсов.
По сравнению с «голым» IPGeoBase «Дадата» удобнее.
Обновляется автоматически. Сервис обновляет справочник по мере выхода новой версии, вспоминать об этом не придется.
Библиотеки не нужны. Справочник доступен по API, к нему подключится любая HTTP-библиотека. Запрос очень простой: отправляешь только IP-адрес и токен, который дают при регистрации на DaData.ru [20].
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 несколько десятков полей, на DaData.ru есть полная спецификация [21].
Мы превратили рабочий, но некрашеный Ту-154 в Airbus А-380.
В экономе возим бесплатно — к API можно сделать 10000 запросов в сутки, просто зарегистрировавшись [22]. Если нужно больше, это будет стоить от 4000 рублей в год.

Автор: rmpl
Источник [23]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/internet-magaziny/266127
Ссылки в тексте:
[1] заранее назвать цену доставки: http://shopolog.ru/metodichka/customer-retention/chto-delat-chtoby-klienty-ne-brosali-korziny-i-bez-oshibok-vvodili-adresa/
[2] API cтандартизации «Дадаты»: https://dadata.ru/api/clean/?utm_source=habrahabr&utm_medium=article&utm_content=full_spec&utm_campaign=geolocation
[3] IPGeoBase: http://ipgeobase.ru/
[4] SypexGEO: https://sypexgeo.net/ru/download/
[5] MaxMind Lite: https://dev.maxmind.com/geoip/geoip2/geolite2/
[6] ip2ruscity: http://ip2ruscity.com/
[7] Perl: http://ipgeobase.ru/files/soft/new_search.pl
[8] Ruby: https://github.com/mokevnin/ipgeobase
[9] Python: https://github.com/greggy/python-ipgeobase
[10] спецификация на сайте справочника: https://sypexgeo.net/ru/docs/sxgeo22/
[11] Python: https://github.com/idlesign/pysyge
[12] PHP Yii: https://github.com/marciocamello/yii2-sypexgeo/
[13] PHP Laravel: https://github.com/scriptixru/sypexgeo
[14] Java: https://github.com/sypexgeo/sypexgeo4j
[15] Ruby: https://github.com/kolesnikovde/sypex_geo
[16] Symfony: https://github.com/yamilovs/SypexGeoBundle/
[17] WordPress: https://github.com/akalevich/wp-sypexgeo/
[18] несколько десятков: https://github.com/maxmind
[19] своего API геолокации: https://dadata.ru/api/detect_address_by_ip/?utm_source=habrahabr&utm_medium=article&utm_content=API_landing&utm_campaign=geolocation
[20] DaData.ru: https://dadata.ru/api/detect_address_by_ip/?utm_source=habrahabr&utm_medium=article&utm_content=dadata_direct&utm_campaign=geolocation
[21] полная спецификация: https://dadata.ru/api/detect_address_by_ip/?utm_source=habrahabr&utm_medium=article&utm_content=full_spec&utm_campaign=geolocation
[22] просто зарегистрировавшись: https://dadata.ru/clean/?utm_source=habrahabr&utm_medium=article&utm_content=full_spec&utm_campaign=geolocation/#registration_popup
[23] Источник: https://habrahabr.ru/post/340466/
Нажмите здесь для печати.