Blog. Just Blog

Определение географического положения по IP-адресу

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Определение страны и города посетителя сайта по его IP-адресу применяется во многих случаях. Например, автоматическая подстройка языка отображения сайта, более точный таргетинг рекламных или информационных блоков сайта, разграничение доступа к разделам сайта для разных источников трафика, а также для многих других целей. Наиболее полные базы географического положения IP-адресов в настоящее время предоставляет компания MaxMind в своей базе GeoLite City. Бесплатный вариант базы содержит данные с точностью до города, его можно скачать с сайта в бинарном формате (в распакованном виде около 30 мегабайт) и в формате CSV (в распакованном виде около 130 мегабайт). На сайте также можно оформить подписку на коммерческие варианты базы, содержащие данные с точностью до улиц и обновляющиеся еженедельно, но это только если вашему проекту действительно требуется такая точность. Обновления бесплатной базы выходят регулярно, обычно в первых числах каждого месяца. Пример работы скрипта с коммерческой географической базой можно посмотреть на сайте MaxMind. Там же на сайте можно скачать бесплатные базы стран мира, почтовые индексы некоторых стран и много других полезных данных. К сожалению, самые вкусности предоставляются только за деньги.

Доступ к базе осуществляется через API, для некоторых популярных языков программирования они расписаны на сайте. Например, для PHP, кроме собственно самой базы, потребуются еще файлы geoipcity.inc, geoip.inc и geoipregionvars.php. Вызов функции определения положения очень простой:
  1. <?
  2. // Подключить класс для работы с базой
  3. include "geoipcity.inc";
  4. // IP-адрес для проверки
  5. $visitor_ip="70.240.110.17";
  6. // Открыть файл базы
  7. $gi=GeoIP_open("GeoLiteCity.dat"GEOIP_STANDARD);
  8. // Получить данные из базы
  9. $record=GeoIP_record_by_addr($gi,$visitor_ip);
  10. // Вывести данные на экран
  11. print_r($record);
  12. // Закрыть соединение с базой
  13. GeoIP_close($gi);
  14. ?>
Результат работы скрипта будет следующим:

geoiprecord Object (
[country_code] => US
[country_code3] => USA
[country_name] => United States
[region] => TX
[city] => Houston
[postal_code] =>
[latitude] => 29.7755
[longitude] => -95.4152
[area_code] => 713
[dma_code] => 618
[metro_code] => 618
)

Отдельные параметры можно получить из соответствующих полей объекта. Для более оперативного доступа к данным можно хранить базу в памяти целиком (смотрите примеры в описаниях API на офсайте), но такое расточительное использование ресурсов допустимо только на выделенных серверах.

Для автоматического обновления базы я написал вот такой небольшой скрипт. Он выкачивает на мой хост архив GeoLite City в бинарном формате, а затем распаковывает его для дальнейшего использования. Время обновления вместе с загрузкой файла составляет 3-5 секунд, так что оно особо не повлияет на работоспособность даже высоконагруженного проекта.
  1. <?
  2. $lnk="http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz";
  3. if ($f1=@fopen($lnk,"r")) {
  4.   // Скачать файл архива и сохранить его локально
  5.   if ($f2=@fopen("GeoLiteCity.dat.gz","w+")) {
  6.     while (!feof($f1)) {
  7.       $data=fread($f1,10000);
  8.       fwrite($f2,$data);
  9.     }
  10.     fclose($f1);
  11.     fclose($f2);
  12.  
  13.     // Распаковать архив в файл GeoLiteCity.dat
  14.     if ($f1=@gzopen("GeoLiteCity.dat.gz","rb")) {
  15.       if ($f2=@fopen("GeoLiteCity.dat","w+")) {
  16.         do {
  17.           $data=gzread($f1,100000);
  18.           fwrite($f2,$data);
  19.         } while ($data!="");
  20.         gzclose($f1);
  21.         fclose($f2);
  22.       }
  23.       else {
  24.         echo "Error create database file";
  25.       }
  26.     }
  27.     else {
  28.       echo "Error open database file";
  29.     }
  30.     // Удалить скачанный архив
  31.     unlink("GeoLiteCity.dat.gz");
  32.   }
  33.   else {
  34.     echo "Error create file";
  35.     fclose($f1);
  36.   }
  37. }
  38. else {
  39.   echo "Error open remote file";
  40. }
  41. ?>
Опытным путем установлено, что при слишком частом скачивании файла базы с сервера MaxMind с одного и того же IP-адреса (что-то около пяти раз в день), доступ блокируется на сутки. Поэтому обновляйте файл только когда это действительно нужно. У меня на сайте он обновляется по планировщику cron 10-го числа каждого месяца. Еще время от времени рекомендуется проверять наличие новых версий файлов API, они тоже иногда обновляются.

Для максимально точного таргетинга в пределах России можете дополнительно использовать данные IpGeoBase. База обновляется ежедневно, данные в ней хранятся в трех вариантах - master (разбивка по городам), slave (подробная информация по округам) и максимально подробная база с указанием районов и провайдеров. К сожалению, данные в базе хранятся в текстовом виде, по строкам, разделенными символами табуляции. На странице примеров можно скачать примеры интерфейсов для взаимодействия с он-лайн сервисом и для парсинга файлов базы. Готовых решений на PHP нет, возможно, что когда-нибудь сделаю.

GeoIP API для PHP 1.15GeoIP API для PHP 1.15

GeoIP.API.PHP.1.15.zip (90,106 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 16866 | Комментариев: 16

Метки: PHP, SEO
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (26.03.2019 в 17:31):
Все, приплыли. База существует теперь только в платном варианте.
ydalenka (24.01.2016 в 22:12):
файлики geoipcity.inc , geoip.inc  и geoipregionvars.php еле нашел, выложил сюда пока что [spam]
ManHunter (12.01.2014 в 18:44):
Они сейчас выложены на гитхабе:
https://github.com/maxmind/geo...php/releases
Сергей (12.01.2014 в 18:37):
Ссылки на файлы geoipcity.inc , geoip.inc  и geoipregionvars.php неверные
404 Not Found
Андрей (08.02.2013 в 21:55):
Как сделать так чтобы у меня, автоматически на сайте выдавалась посетителю информация о ближайшем офисе компании по определению его географического положения, достаточно регионного, городского будет лучше.
Валерий (07.02.2010 в 20:52):
Господин! Я вас знаю
:)
ManHunter (01.02.2010 в 03:14):
... да бесплатно и побыстрее
Сергей (01.02.2010 в 03:03):
Напишите плзз скриптик на perl для обновления базы GeoLite City, чтобы из cron запускать.
ManHunter (26.01.2010 в 14:01):
ставишь на site.ru скрипт, который после определения города делает переадресацию:

if (strtolower($city)=="moscow") {
  header("Location:http://moscow.site.ru");
  exit;
  // или
  echo '<meta http-equiv=Refresh content="0; url=http://moscow.site.ru">';
  echo '<script type="text/javascript">document.location.href="http: //moscow.site.ru";</script>';
  exit;
}
elseif (strtolower($city)=="kazan") {
  // обработка Казани
}
else {
  // действия по умолчанию
}

как-то так
Дмитрий (26.01.2010 в 13:56):
Установил у себя на сайте, работает отлично.
Как можно реализовать возможность автоматического открытия заданной страницы на сайте по [city] => Moscow или Kazan???
Что бы для Moscow, например открывалась сразу http://www.moscow.site.ru, а для Kazan: http://www.kazan.site.ru
DiFor (19.11.2009 в 16:44):
еще очень неплохо было-бы добавить к семи апи гугл мапс и вывод на "экран" непосредственно саму карту с отмеченной точкой местоположения. latitude, longitude предоставляемый геоип поможет в этом)
ManHunter (25.09.2009 в 10:55):
Да я ж понимаю :)) Больше методов, хороших и разных :))
1n1t (25.09.2009 в 10:54):
ManHunter, понял Вашу мысль, не корысти славы ради, а для коллекции, один из вариантов, у кого шелл под лохматыми, думаю сами сообразят что к чему.
ManHunter (25.09.2009 в 10:34):
1n1t, не на всех хостинговых серверах есть доступ к шеллу, так что мне пришлось реализовывать обновление средствами PHP. А на выделенном сервере вполне можно и твоим методом обновляться.
1n1t (25.09.2009 в 10:30):
ManHunter, веьма признателен.

#!/bin/sh
cd /path/to/dir/file/dat
wget -qO GeoLiteCity.dat.gz http://geolite.maxmind.com/dow...eCity.dat.gz
gzip -d ./GeoLiteCity.dat.gz

пустив данный сценарий по крону, он пришлет уведомление автоматом только в случае ошибки (невозможности либо скачать файл или распаковать его.)
INC (23.09.2009 в 22:23):
Thanks

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.06 сек. / MySQL: 2 (0.0039 сек.) / Память: 4.5 Mb
Наверх