この記事をシェアする

【PHP】クローラーからのアクセスかどうかを判定する仕組みを作ってみるべ

サイト・システムを構築する上で、人間からのアクセスか、クローラー(bot)からのアクセスか振り分けなきゃならないケースってそれなりにあるんじゃないかと思う。
恐らくだが、そんな処理を実装しようってなった時、クライアントのユーザーエージェントを見て、このユーザーエージェントだったらbot、そうじゃないなら人間……って感じで作る人がほとんどじゃないかと思う(もしくはIPアドレスによって)。しかしながらクローラー(bot)ってのは色んな会社が運用しておりたくさん種類があるため、それらのユーザーエージェントを網羅するのは非常に骨が折れることである。

そんな骨の折れることをやって、しかもJSONでリスト化してまとめてくれているとっても偉い人がいる。今回はそのおこぼれに預かりつつ、PHPでbotからのアクセスかどうか判定する仕組みを作ってみた。

<?php
// jsonファイルを落としてくる
$json = file_get_contents('https://raw.githubusercontent.com/monperrus/crawler-user-agents/master/crawler-user-agents.json');
// 落とすのに失敗したら終了
if ($json === false) {
    return;
}

// jsonを配列に変換
$arr = json_decode($json, true);
// 変換できなかったら終了
if ($arr === null) {
    return;
}

// 正規表現のパターンをまとめた配列を作る
$pattern_list = [];
foreach ($arr as $key => $value) {
    $pattern_list[] = $value['pattern'];
}

// パターン配列を「|」で連結した文字列に変換
$pattern_list_string = implode('|', $pattern_list);

// クライアントのユーザエージェントを取得
$ua = $_SERVER['HTTP_USER_AGENT'];
// 作成したパターン文字列を使い正規表現によるマッチングを行う
$result = preg_match('/' . $pattern_list_string . '/', $ua) === 1;

まあ、判定の度にあちらさん(Github)のサーバまでJSON読みに行くのはあんまりお行儀がよろしくない&ネット経由でのアクセスになるから処理速度的にも美味しくないので、実際はcronで一日一回ローカルにJSONを落としてきて、それをfile_get_contentsで読み込むようにしている。

この記事をシェアする