きっかけ
gokeでは100万ユーザーを目指してwebサービスを制作している。
「100万ユーザー」の定義は個々のサービスのユニークユーザーの合算なのだが、これまでこの数字の集計はGoogle Analyticsで行っていた。
Google Analyticsはbotなどのアクセスを除外してくれているので、Google Analyticsが弾き出してくれた数字をただ合算すればいいだけなのだが、集計に手間がかかり、もっとリアルタイムで見られる方法はないだろうかと検討を始めた。
botを除外する方法
Google Analyticsに頼らずに集計するには大きく2つの課題がある。
- サービス単位でユニークにすること
- botを除外すること
1については同じ人が100回アクセスしてもユーザー数は1とカウントすべき、ということなので、初回のアクセス時にcookieを発行してcookieを持っていれば次回以降はカウントしない方式にした。
問題は2の方で、botを除外するには何がbotであるかを判別する必要があるため、botの一覧とそのアクセスがその一覧に属するものからのアクセスかどうかを確認する手段が必要になる。なお、ここでいうbotとはGoogleやTwitterなどが世に放っている情報収集のプログラム(いわゆるcrawler)だけではなく、個人やよくわからない団体からのスクレイパーの類も含む。
botかどうかの判別には通常User Agent(どんなブラウザなのかの情報)を見るので、PHPだと下記で実行できる。
$ua = $_SERVER['HTTP_USER_AGENT'];
その上で、出てきたUser Agentがbotかどうかの判別なのだが、あれこれ調べた結果、下記の2段階で概ね解決しそう。
- "Mozilla" で始まらないUser Agentは「ユーザーではない」可能性が高いので除外
- "Mozilla"で始まっても特定の文字列を含む場合は除外
1については、歴史的な背景で現在一般で利用されているブラウザのUser Agentは一様に「Mozilla」で始まるようで、これを満たさない場合は何らかのツールでスクレイピングをしている可能性がある。場合によっては独自で作ったブラウザからアクセスしてくれている可能性もあるが、それはかなりレアなケースなので許容できる巻き込みだとすると「Mozilla」で始まらない場合は除外する方針で良さそう。
2に関しては有名どころのbotや、UAにbotを示す文字列が含まれていればbotと判断するというもので、PHPで書くと
function isBot($bot=false){
$ua = $_SERVER['HTTP_USER_AGENT'];
$bot_arr = array(
"google"
,"twitter"
,"facebook"
,"Baiduspider"
,"bingbot"
,"Yeti"
,"NaverBot"
,"Yahoo"
,"Tumblr"
,"livedoor"
,"hatena"
,"bot"
,"crawler"
,"spider"
);
foreach ($bot_arr as $value) {
if (stripos($ua, $value) !== false) {
return true;
}
}
return false;
}
上記で判定すれば概ね取り除けそう。