PHP

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

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

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

Результат работы скрипта будет следующим:
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 секунд, так что оно особо не повлияет на работоспособность даже высоконагруженного проекта.
<?
$lnk="http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz";
if ($f1=@fopen($lnk,"r")) {
  // Скачать файл архива и сохранить его локально
  if ($f2=@fopen("GeoLiteCity.dat.gz","w+")) {
    while (!feof($f1)) {
      $data=fread($f1,10000);
      fwrite($f2,$data);
    }
    fclose($f1);
    fclose($f2);
 
    // Распаковать архив в файл GeoLiteCity.dat
    if ($f1=@gzopen("GeoLiteCity.dat.gz","rb")) {
      if ($f2=@fopen("GeoLiteCity.dat","w+")) {
        do {
          $data=gzread($f1,100000);
          fwrite($f2,$data);
        } while ($data!="");
        gzclose($f1);
        fclose($f2);
      }
      else {
        echo "Error create database file";
      }
    }
    else {
      echo "Error open database file";
    }
    // Удалить скачанный архив
    unlink("GeoLiteCity.dat.gz");
  }
  else {
    echo "Error create file";
    fclose($f1);
  }
}
else {
  echo "Error open remote file";
}
?>

Опытным путем установлено, что при слишком частом скачивании файла базы с сервера MaxMind с одного и того же IP-адреса (что-то около пяти раз в день), доступ блокируется на сутки. Поэтому обновляйте файл только когда это действительно нужно. У меня на сайте он обновляется по планировщику cron 10-го числа каждого месяца. Еще время от времени рекомендуется проверять наличие новых версий файлов API, они тоже иногда обновляются.

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