AdsBot-Google問題とPHPのstrposの仕様

管理サイトの一部ではGoogleアナリティクスを使わず、他のアクセス解析ツールを使ってます。
しかしAdWordsに出稿していると、ページ品質のチェックをしていると思われるボットのアクセスログが残ります。
多分Googleアナリティクスを使ってれば勝手に除外されるのかもしれませんが、他社のは記録されてしまいます。
そうすると、特にアクセスが少ないサイト程数字が見辛くなります。
これらのボットはそのまま去りますので、何も施さないととりわけ直帰率が上がったように感じます。
少し前までPtengineを利用してましたが、Ptengineにはフィルタ機能があるので、これらのボットが残すログはGoogle本社があるカリフォルニア等アメリカの場合が多いことから日本以外を表示させないようにフィルタしてました。
しかし、このフィルタ機能、何回かアクセスしてると勝手に外れちゃうんですよね。
それが面倒で重い腰を上げて根本的に対処しようと思ってあれこれしてると、Ptengineは何と3ヶ月しかログが残らないことを知って、Ptengineは止めました。
まぁ、今思うとサブとして併用するのは良いかもしれませんけど。


Ptengineでは訪問者のユーザーエージェントが分からないので、これらのボットはどんなユーザーエージェントになっているか検索してみると、「AdsBot-Google」や「AdsBot-Google-Mobile」、AdSenseなら「Mediapartners-Google」といった文字列が使われることが分かりました。
感情的には鬱陶しいのでhtaccessやrobots.txtで拒否したいと思ったのもの、流石にページ評価するために来ていると思われるボットを拒否するのはまずいのではと実行は出来ませんでした。
しかし、ふとPHPの中で振り分けてボットの場合アクセス解析のjsを書き出さないようにすれば良いじゃんと気付きました。
テストサイトではアクセス解析に残らないようにjsが書き出されないような処理をしてるんですが、それみたいな感じにすれば良いと。
PHPを書き足して、自分でユーザーエージェントを変更してテストしてみると、上手くいきました。

PHPのstrposの仕様


しかし実際に本番環境に設置して様子を見てみると、どうも相変わらずボットがアクセス解析に残る模様…。。
そこで重い腰を上げて、所謂生ログ?を吐くPHPを設置して、どんな情報が残るかやってみることにしました。
すると、予想通り「AdsBot-Google-Mobile」の文字列が出てきてくれました。
では何故うまくいかない!とプログラムを検証すると、自分の記述が間違っていたようです(笑)
最初はこれらの文字列が含まれていたらということで「if (strpos($ua, 'AdsBot-Google'))」のようにやっていたのですが、PHPの場合文字列の初めに一致したら「0」が返るんですね。
VBのInStrと同等のものと思って使ったけど、0が返るなら上記のように省略形で書けば当然Falseが返ります。
自分がテストした時はユーザーエージェントの文字列の途中を変えたから0以上の値が返り、うまくいってたのです。
しかし実際のボットは生ログを取得してみて、固有の文字列は先頭にありました。
なので、Falseが返りボットではないとの処理になっちゃいました。
ということで、以下のようにするとうまく動くようになり、ボットがアクセス解析にほぼ残らなくなりました。

$ua = $_SERVER['HTTP_USER_AGENT'];
if ((strpos($ua, 'Googlebot') === false) && (strpos($ua, 'Mediapartners-Google') === false) && (strpos($ua, 'AdsBot-Google') === false) && (strpos($ua, 'Slurp') === false) && (strpos($ua, 'msnbot') === false) && (strpos($ua, 'bingbot') === false)) {
	$bot = false;
} else {
	$bot = true;
}


このボットでもなくてこのボットでもなくてこのボットでもなくて…どのボットでもなかったら一般ユーザー、どれか該当したらボットといった感じでしょうか。
とりあえず今は簡素なものでいいやと思ってるので&&で数珠つなぎにしてますが、もっと色々なボットに対応させたくなった場合は以下のリストとプログラムを少し変えて使おうと思います。


http://qiita.com/haco99/items/c8321b2992080364d08c


また、このリストには載ってないので備忘録として書いておきます。


「SurveyBot」


Whoisのボットのようです。
今回生ログを取得してみてこんなボットが来てました。
上記の多ボット対応版にする場合はこのボットも追加しておきたいと思います。

尚も記録されるボット


ほぼ残らなくなったと書いたように、残念ながら何故かアクセス解析ではAdWords経由で記録されてるのにAdWords管理画面ではクリックされていないアクセスがあり、再度生ログを調べてみました。
どうやらユーザーエージェントにはボットらしい文字列は含まれていないけど、リモートホストが「google-proxy-X-X-X-X.google.com」といったボットらしきログがあり、アクセス解析に記録されてた数値とも一致しました。
1回につき2度アクセスがあり、1度目の数秒後に違うIPから2度目のアクセスがあったり、如何にもボットくさいと思います。
リモートホストに「google-proxy」が含まれていたらボット、のような処理にしてしまえば楽ですが、ググってみるとこのアドレスはGoogle翻訳Chromeのデータ圧縮機能でも使われているようです。
まぁGoogle翻訳はいいとして、データ圧縮機能を使ったユーザーを切り捨てるのはちょっとなぁと躊躇してしまいます。
妥協するしかないかなーと思ったりしますが、また色々考えます。


追記


広告経由で来たデータ圧縮機能を利用したユーザーの初動が記録されないことを妥協する形で対応しました。

$host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
$rf = $_SERVER['HTTP_REFERER'];
if ((strpos($host, 'google-proxy-') === 0) && (strpos($rf, 'utm_campaign'))){
	$bot = true;
}


リモートホストが「google-proxy-X-X-X-X.google.com」で、且つ広告経由だったらjsを書き出さない、といった感じです。
データ圧縮機能を利用していたユーザーがたまたま広告経由でアクセス、ということもあるかもしれませんが、大規模なサイトではないしそういったケースは年に1回あるかどうかというくらいだと思うので、それだったら数日に1度は来るユーザーエージェント設定されてないボットが除外された方が良いかなと。
ボットは直帰するので一切記録されることはないと思います。もしデータ圧縮機能を利用していたユーザーが他のページへ遷移した場合は上記条件分岐の後ろの条件に一致しなくなるので、以後記録されるはずです。
ただ初動が記録されないので、アクセス解析だけを見たら広告経由で来たユーザーとは判断できないためこれはこれでデメリットですね。。
でも後ろの条件を付けることで、オーガニックや他サイト経由ならデータ圧縮機能を利用していてもちゃんと記録されるので、この辺で妥協かなと思います。