IPアドレスから位置情報を取得する

訪問者の位置情報が知りたい

Webサイトにどの地域からアクセスがあるか知りたいなーという話が周りでちらほらと出ていたのですが、会員登録制ではないしFBと連携している訳でもないのでソーシャルグラフの情報も取得できないという状況。
なので精度は落ちますが、IPアドレスから大体の位置を割り出せるサービスを探して見ることに。

GeoIP Database

ちょちょっと探してみたところ、GeoIP Databasesというサービスを発見。
位置情報DBはローカルに保存し、その情報をAPI経由で検索・取得するという方式。
メインターゲットはUSっぽいので、取得できる位置情報にはUS onlyな情報もある。
(郵便番号、Metro Code、Area Codeなど…)

位置情報DBには有償版と無償版があり、精度は勿論有償版のほうが高い。

試してみる

とりあえず無償版の位置情報DBで試して見ることに。

C,Java,Perl,PHP,Rubyなど主要言語のAPIは準備されている
今回は個人的な趣味でPerlAPIを選択。
PerlAPIには2種類あり、違いは以下の通り。

  • Geo::IP Module
    • 動作は速いが、Cのライブラリを事前にインストールする必要がある
  • Geo::IP::PurePerl Module
    • 動作は遅いが、Cのライブラリをインストールする必要なし

速度が欲しいのでGeo::IPを選択。

インストール手順

まずはCライブラリを取得

cd /tmp
wget http://www.maxmind.com/download/geoip/api/c/GeoIP.tar.gz

解凍してインストール

tar xvzf ./GeoIP.tar.gz
cd GeoIP-1.4.8
./configure
make
make check
make install

CPAN経由でGeo::IPをインストール

cpanm -v Geo::IP

位置情報DBを取得

cd /tmp
wget http://www.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gzip -d ./GeoLiteCity.dat.gz

試してみる

ソース

#!/usr/bin/env perl

use strict;
use warnings;
use Geo::IP;

my $gi = Geo::IP->open("/tmp/GeoLiteCity.dat", GEOIP_STANDARD);
my $record = $gi->record_by_name("google.com");

print "country_code  : ", $record->country_code, "\n";
print "country_code3 : ", $record->country_code3, "\n";
print "country_name  : ", $record->country_name, "\n";
print "region        : ", $record->region, "\n";
print "region_name   : ", $record->region_name, "\n";
print "city          : ", $record->city, "\n";
print "postal_code   : ", $record->postal_code, "\n";
print "latitude      : ", $record->latitude, "\n";
print "longitude     : ", $record->longitude, "\n";
print "time_zone     : ", $record->time_zone, "\n";
print "area_code     : ", $record->area_code, "\n";
print "continent_code: ", $record->continent_code, "\n";
print "metro_code    : ", $record->metro_code, "\n";

実行結果

country_code  : US
country_code3 : USA
country_name  : United States
region        : CA
region_name   : California
city          : Mountain View
postal_code   : 94043
latitude      : 37.4192
longitude     : -122.0574
time_zone     : America/Los_Angeles
area_code     : 650
continent_code: NA
metro_code    : 807

感想

  • ローカルに位置情報DBをDLするので、データローカリティ的な意味で早い。
  • 位置情報DBが毎月更新されるらしいので、運用するには定期更新バッチを作成する必要はある。
  • 地名がローマ字なのはUSのサービスだから仕方ないとはいえ微妙。
  • ログの分析軸として位置情報は大変有用なので、導入する価値は大いにあると思う。