トップに戻る
【PHP】ユーザーエージェントからクローラー(bot)を判別する
 > 
PHP > 
プログラミング > 
HOME > 
2025/07/25
2025/10/03

【PHP】ユーザーエージェントからクローラー(bot)を判別する

ブログで投稿の閲覧数などを記録する処理を作る場合、純粋なアクセスユーザーだけのデータを計測したいとなると、WEB上にはびこるクローラー(SEO用の自動ページ解析システム)によるアクセスを省いた数値を計測しなければなりません。

結論から言いますが、以下のコードで判別することが可能です。(ほとんど検証してないので、100%完璧な処理ではないと思います。大体これでOK、という感じ。)

$ua = strtolower($_SERVER["HTTP_USER_AGENT"]);
return stripos($ua, "bot") !== false || stripos($ua, "spider") !== false;

以下で、コードの説明をちょっと詳細にしていきます。

【注意点】ユーザーエージェントの利用

この記事を書いていてあれですが、ユーザーエージェントについて、Google Chromeを筆頭に、各ブラウザで廃止の流れが出てきています。

参考:Update on User-Agent String Reduction in Chrome

参考先の記事を要約すると、以下のようなことが書いてあります。

えーと、ユーザーエージェントは現在たくさんの情報を文字列に入れているけど、それを段階的に減らしていくよ。
もっと情報量をすっきりさせるために、User Agent Client Hints APIでスマートにデータを扱えるようにしていくから、今後はそっちを参照していくようにすると、いいかも~

参考:Update on User-Agent String Reduction in Chrome

2025年7月現在では本記事のプログラムが正常にクローラーを弾いてくれているのは確認済みですが、今後どこかのタイミングで要改修案件になるかもしれません。

プログラム説明

冒頭のプログラムについて、以下の順序で説明します。

  1. ユーザーエージェントの文字列を全て小文字に
  2. 指定の文字列が含まれているかどうか検索

ユーザーエージェントの文字列を全て小文字に

まず、下記コードの部分では、ユーザーエージェントの文字列を全て小文字にしています。

$ua = strtolower($_SERVER['HTTP_USER_AGENT']);

strtolowerメソッド

/** Chromeのユーザーエージェント文字列の変換例 */

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36

↓↓小文字に変換↓↓

mozilla/5.0 (x11; linux x86_64) applewebkit/537.36 (khtml, like gecko) chrome/51.0.2704.103 safari/537.36

大文字だけ小文字になっているのがわかると思います。

今回のプログラムでは、クローラーかどうかをユーザーエージェントの文字列内に、それらしき文字列が含まれているかどうかで判定するため、小文字大文字ごとに判定処理を書かなくてもいいよう、全て小文字にしてから判定処理を行っています。

指定の文字列がUAに含まれているか検索

次に、下記コードでユーザーエージェントの文字列内に、クローラー特有の文字列かないかを検索しています。

stripos($ua, "bot") !== false || stripos($ua, "spider") !== false;

まず、striposメソッドは、第一引数の文字列のうち、第二引数に指定した文字列が含まれていれば、第二引数が含まれている部分の開始位置(先頭から何文字目に含まれているか)を返し、含まれていない場合はFalseを返します。

つまり、上記のコードは、ユーザーエージェントの文字列に「bot」あるいは「spider」の文字列が含まれいればTrue、どちらも含まれていなければFalseを返す、ということをしています。

まあ、正直これだけでクローラーを弾ききれないのは管理人もわかっていますが、クローラーあってもなくてもそこまで閲覧数に差は出ないので、これぐらい気休め程度のコードにしておいても問題はないでしょう。

spiderとbotって?

「bot」と「spider」としているのは、なんかクローラーにはそれ系の単語が入っている名前のものが多いからです。

ユーザーエージェントにクローラー以外で上記単語が入ることはほぼないというか、入っていたらそれは命名の仕方に問題がある、という話になるので、この2つの単語でクローラーかどうかを判定しています。

詳細にやるなら、クローラーの名前をAPIか何かでまとめておいて、それを受け取る、とかにした方がいいでしょうね。

str_containsは使わない?

PHP8.0から、「文字列が含まれているかどうか」を判定する専用のメソッドとして「str_contains」メソッドが追加されました。

別にどっちで書いてもいいんですけど、基本的にstriposメソッドの方が処理速度が高速らしいので、管理人はそちらを使っています。

まあ、たかがこれだけのコードなら、str_containsでも速度に大した差は出ないと思うので、どっちでもいいです。

SHARE