Google Analyticsのデータからアクセスランキングを生成するPerlスクリプト

2009年9月20日

当ブログ「Publickey」でアクセスランキングの表示を始めました。そのために作成したPerlのコードを、せっかくなので公開します。

作成したのは、Google AnalyticsからAPI経由でランキング情報を取得して、それをHTML形式で出力するPerlのコードです。

この方法が優れている点は、統計処理済みのランキング情報をGoogle Analyticsから取得するためWebサーバにほとんど負荷がかからない点です。Perlのコードもシンプルで導入は容易だと思います。

コードは、「Using Perl for Google Analytics API « Patrick Hartman's Log」を基に、不要な部分の削除や変更を行ってシンプルにし、HTMLの出力部分などを追加したものです。ただし僕はPerlのプログラミングの知識があまりなくマニュアルを見ながらコードをいじったので、もし変なところがあったら教えてください。

基本的な使い方は、まず下記の部分にGoogle Analyticsへログインするときのユーザー名(xxxx@gmail.comのxxxxの部分)とパスワード、そしてGoogle AnalyticsのプロファイルIDと、ランキングを何位までにしたいかを設定してください。

my $token = &gaGetToken('User-ID','Passwd');
my $profileid = "XXXXXXXX";
my $maxresult = 10;

プロファイルIDとは、Google AnalyticsのWebサイトでレポートを表示したときに用いるURLの「id=」の後ろに表示されている数字です(例:15249720)。

デフォルトでは今日から過去7日分のデータを集計しています。もし期間を変更したい場合には、以下の「$tm=」の右辺を変更してください。この式は7日×24時間×60分×60秒で7日分の秒数を求めています。7日を14日に変更すれば過去2週間分、31日に変更すれば過去1カ月分が集計対象となります。

$tm = localtime(time-7*24*60*60);
my $wago = sprintf "%04d-%02d-%02d",$tm->year+1900, $tm->mon+1,$tm->mday;

Google Analytics APIの機能や使い方についての詳細は、グーグルのページを参照してください(Developer's Guide - Google Analytics - Google Code

重要な注意!:このコードは、Webサーバから見えるところには置かないでください。第三者にあなたのログイン名とパスワードを盗まれてしまいます。Webサーバに見えない位置にコードを設置して、出力だけをWebサーバから見える場所に書き込むようにするべきです。

そのためには、例えば次のようなシェルスクリプトを用意するとよいのではないでしょうか。

/usr/bin/perl /usr/local/RankingByGoogleAnalytics.pl > /home/www/ranking.inc

上記のシェルスクリプトをcronで定期的に実行することで、Webサーバから見えるところに自動的にランキングのファイルが生成されます。

また、TypePadやココログなどのブログサービスを利用していて、サーバではスクリプトを実行できない場合には、別のサーバを借りてこのコードを実行する方法も考えられるでしょう。その場合は、出力形式をJSONに変更したうえでJavaScriptで読み込む方法や、AtomPPなどを使ってブログサーバに書き込んでからテンプレートでincludeする方法などが考えられます。いろいろ工夫してみてください。

このコードはさくらインターネットで動作を確認していますが、ホスティング先によってはPerlのバージョンやライブラリの違いで動作しないかもしれません。どうかご了承を。また分からない部分や変な部分があれば、どうぞコメント欄などでご指摘ください。

以下、ソースコードです。

#!/usr/bin/perl -w
use strict;
use Encode;
use LWP::UserAgent;
use XML::Simple;
use Time::localtime;

# authenticate with the API to receive token
my $token = &gaGetToken('User-ID','Passwd');
my $profileid = "XXXXXXXX";
my $maxresult = 10;
$maxresult++;

my $tm = localtime();
my $tdy = sprintf "%04d-%02d-%02d",$tm->year+1900, $tm->mon+1,$tm->mday;
$tm = localtime(time-7*24*60*60);
my $wago = sprintf "%04d-%02d-%02d",$tm->year+1900, $tm->mon+1,$tm->mday;

my $url = "https://www.google.com/analytics/feeds/data?"
."ids=ga%3A$profileid&"
."dimensions=ga%3ApagePath%2Cga%3ApageTitle&"
."metrics=ga%3AuniquePageviews&"
."sort=-ga%3AuniquePageviews&"
."start-date=$wago&"
."end-date=$tdy&"
."max-results=$maxresult";

my $pageviews = &gaDataFeed($url, $token);

# create a xml object for the response
my $xml = new XML::Simple(KeyAttr=>[]);
my $tree = $xml->XMLin($pageviews);

# iterate through each entry in the xml
my $i = 0;
print "<ol>";

foreach my $e (@{$tree->{entry}}) {
# eliminate toppage(/) from ranking
if ($e->{'dxp:dimension'}->[0]->{value} eq "/") { next; }

print "<li>";
print "<a href=\"";
print $e->{'dxp:dimension'}->[0]->{value};
print "\">";
print Encode::encode("utf8",substr($e->{'dxp:dimension'}->[1]->{value},0,22));
print "...</a></li>";

$i++;
if ($i >= ($maxresult -1)) { last; } 
}
print "</ol>";


# this sub will return the token you need to authenticate api requests
# you need to pass your ga login and password to it
sub gaGetToken {
# arguments passed to this function
my $user = $_[0];
my $pass = $_[1];

# create user agent object
my $ua = LWP::UserAgent->new;
$ua->agent("MyApp/0.1 ");

# Create a request
my $req = HTTP::Request->new(POST => 'https://www.google.com/accounts/ClientLogin');
$req->content_type('application/x-www-form-urlencoded');
$req->content("accountType=GOOGLE&Email=$user&Passwd=$pass&service=analytics&source=companyName-applicationName-versionID");

# Pass request to the user agent and get a response back
my $res = $ua->request($req);

# declare variable
my $token;

# Check the outcome of the response
if ($res->is_success) {
    # look at the result
    if ($res->content =~ m/(?<=Auth=).*/im) {
        # store token so it can be used in subsequent requests
        $token = $&;
    }
}
else {
    # return the error if there was a problem
    return "error: ". $res->status_line;
    die;
}

# return the token
return $token;
}


# this sub will return the xml from a datafeed request
# you need to pass your token to it
sub gaDataFeed {
# arguments passed to this function
my $url = $_[0];
my $token = $_[1];    

# create user agent object
my $ua = LWP::UserAgent->new;
$ua->agent("MyApp/0.1 ");

# add authorization to headers
my @headers = (Authorization => "GoogleLogin Auth=$token");

# request page
my $res = $ua->get($url, @headers);

my $content;

# if the request was successful...
if ($res->is_success) {
    # this is the xml response
    $content = $res->content;
} else {
    # return the error if there was a problem
    return "error: ". $res->status_line;
    die;
}

# return the xml
return $content;
}

このエントリーをはてなブックマークに追加
follow us in feedly

タグ : Perl , 編集後記



≫次の記事
報告:記事のレコメンド機能として「newziaコネクト」を導入しました
≪前の記事
プログラミング言語のCOBOLが50周年、情報処理学会が鳩山由紀夫氏の寄稿を公開ほか。ITNewsWeekend 2009年9月19日号

Loading...

Blogger in Chief

photo of jniino Junichi Niino(jniino)
IT系の雑誌編集者、オンラインメディア発行人を経て独立。新しいオンラインメディアの可能性を追求しています。
詳しいプロフィール


Publickeyの新着情報をチェックしませんか?
Twitterで : @Publickey
Facebookで : Publickeyのページ
RSSリーダーで : Feed



Publickey 最新記事 10本

Publickey Topics 最新記事 10本


PR - Books


fig

fig

fig

fig



blog comments powered by Disqus