filtering-bot-traffic について
PostHog分析でボットトラフィックを識別、測定するスキルです。人間、クローラー、自動化、AIエージェントの流入を区別したいチーム向けに、仮想プロパティ、HogQL関数、カスタムルールを扱います。
主な機能
- 01トラフィックを種類とカテゴリで分類
- 02分析からボット流入を除外
- 03名前や運営元別に流入を集計
- 04HogQL関数でユーザーエージェントを分析
- 05カスタムボットルールを管理
活用シーン
- 01ページビューに占めるボット比率の測定
- 02サイトを訪れるクローラーと運営元の特定
- 03AIエージェント流入の個別測定
- 04未検出クローラーの分類ルール追加
MCP 対応
PostHogのカスタムボットルールを一覧、作成、削除するMCPツールの利用方法を説明します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ posthog/ ai-plugin --skill filtering-bot-trafficインストール後、Claude Code で/filtering-bot-trafficを入力して読み込まれたか確認します。
詳細
ボットトラフィックのフィルタリングと測定
PostHog はすべてのリクエストをユーザーエージェントに基づいて分類するため、HogQL が実行されるあらゆる場所(SQL エディター、インサイト、トレンド、Web 分析の内訳)で、人間とボット、クローラー、AI エージェントを見分けられます。このスキルでは、エージェントであるあなたが、この分類を使って次のことを行う方法を学びます。
- ボットを除外し、分析結果を人間のトラフィックだけにする
- 自動化されたトラフィックの量と、その原因となっているボットや運営者を測定する
- 測定する価値のある AI エージェントのトラフィックと、除外すべきノイズを分ける
- 適切な画面を選ぶ。インサイトビルダーには仮想プロパティ、生の SQL には関数を使用する
リアルタイム(「現在」、直近 30 分)のボットに関する質問や Live タブのタイルには、代わりに exploring-live-traffic スキルを使用してください。このスキルは、過去の期間、保存済みインサイト、ダッシュボード、フィルタリングを対象としています。
このスキルを使用するタイミング
ユーザーが次のことを求めている場合に使用してください。
- ボットを除外またはフィルタリングする(「ページビューからボットを除外して」、「人間のみ」)
- 自動化されたトラフィックの割合を把握する(「トラフィックの何%がボットですか?」「AI クローラーはどのくらいいますか?」)
- サイトを訪れるボットを調べる(「どのクローラーが訪問していますか?」「ChatGPT はドキュメントを読んでいますか?」)
- トレンドをトラフィックの種類やボット名で分類する
- AI エージェントや AI 検索のトラフィックを特に測定する(AEO/回答エンジンでの可視性)
Live タブ、リアルタイムの数値、ボットの分単位のグラフには使用しないでください。これらは exploring-live-traffic の対象です。
分類を利用する方法
同じ分類を利用する方法は 2 つあります。インサイトビルダーやフィルターでは 仮想プロパティ を優先し、手書きの SQL や、仮想プロパティでは取得できない値が必要な場合は 関数 を使用してください。
仮想プロパティ(インサイトビルダー、フィルター、内訳)
これらはユーザーエージェントを自動的に読み取るため($raw_user_agent がない場合は $user_agent にフォールバックします)、値を渡す必要はありません。イベントプロパティを選択できる場所であれば、どこでも利用できます。
| プロパティ | 値 |
|---|---|
$virt_is_bot | ブール値 — ボット/クローラー/自動化の場合は true |
$virt_traffic_type | Regular、AI Agent、Bot、Automation のいずれか |
$virt_traffic_category | より詳細なカテゴリ。例:ai_crawler、ai_search、ai_assistant、search_crawler、seo_crawler、social_crawler、monitoring、http_client、headless_browser、no_user_agent、regular |
$virt_bot_name | 表示名。例:Googlebot、GPTBot、ClaudeBot |
$virt_bot_operator | ボットを運営する企業。例:Google、OpenAI、Anthropic |
HogQL 関数(生 SQL)
ユーザーエージェントを明示的に渡してください。coalesce(nullIf(properties.$raw_user_agent, ''), properties.$user_agent) を使用すると、サーバー側($raw_user_agent)と JS SDK($user_agent)の両方のキャプチャをカバーできます。nullIf により、空の $raw_user_agent が実際の $user_agent を隠してボットと誤判定されるのを防ぎます。これは、仮想プロパティが内部で使用する式と同じです。
| 関数 | 戻り値 |
|---|---|
isLikelyBot(ua) | UA がボット/自動化パターンに一致する場合は true(空の UA もボットとして扱います) |
getTrafficType(ua) | AI Agent/Bot/Automation/Regular |
getTrafficCategory(ua) | サブカテゴリ。人間の場合は regular |
getBotType(ua) | 同じサブカテゴリですが、人間の場合は空文字列です。フィルタリングに便利です |
getBotName(ua) | ボット名。人間の場合は空文字列 |
getBotOperator(ua) | 運営者/企業名。人間の場合は空文字列 |
トラフィックの種類 — 除外するものと残すもの
getTrafficType/$virt_traffic_type は、すべてのリクエストを4つのカテゴリに分類します。カテゴリごとにデフォルトの対応は異なるため、すべてをノイズとして扱わないでください。
| 種類 | 内容 | デフォルトの対応 |
|---|---|---|
Regular | 人間の訪問者 | 残す |
AI Agent | AI クローラー、AI 検索、AI アシスタント(GPTBot、ClaudeBot、PerplexityBot、ChatGPT-User) | 多くの場合、計測し、除外しません。AI ツールがコンテンツを見つけ、引用するための手段です |
Bot | 検索クローラー、SEO ツール、ソーシャルプレビュー、監視ツール(Googlebot、AhrefsBot、Pingdom) | 人間の指標から除外し、SEO 用に個別に追跡します |
Automation | HTTP クライアントとヘッドレスブラウザー(curl、python-requests、Puppeteer) | 通常はノイズのため、除外します |
レシピ
インサイトからボットを除外する(人間のみ)
プロパティフィルター $virt_is_bot exact false を追加します。
{ "key": "$virt_is_bot", "value": ["false"], "operator": "exact", "type": "event" }
任意の TrendsQuery/FunnelsQuery などの properties に追加します。これにより、保存済みデータを変更することなく、訪問者数、セッション数、ページビュー数が人間のトラフィックのみを反映するようになります。
より限定的な範囲を除外するには(例:AI エージェントは残し、監視と自動化は除外する場合)、代わりに $virt_traffic_type または $virt_traffic_category を operator: is_not でフィルタリングします。
自動化されたトラフィックの割合
ページビューのトレンドを $virt_traffic_type で分類します。
{
"kind": "TrendsQuery",
"dateRange": { "date_from": "-30d" },
"series": [{ "kind": "EventsNode", "event": "$pageview", "math": "total" }],
"breakdownFilter": { "breakdown": "$virt_traffic_type", "breakdown_type": "event" },
"trendsFilter": { "display": "ActionsBarValue" }
}
アクセスしているボット/運営者
ボットに絞り込み、名前(または企業単位の場合は $virt_bot_operator)で分類します。
{
"kind": "TrendsQuery",
"dateRange": { "date_from": "-30d" },
"series": [{ "kind": "EventsNode", "event": "$pageview", "math": "total" }],
"properties": [{ "key": "$virt_is_bot", "value": ["true"], "operator": "exact", "type": "event" }],
"breakdownFilter": { "breakdown": "$virt_bot_name", "breakdown_type": "event", "breakdown_limit": 25 },
"trendsFilter": { "display": "ActionsBarValue" }
}
AI エージェントのトラフィックを個別に計測する
$virt_traffic_type を exact AI Agent でフィルタリングし、$virt_bot_operator で分類すると、どのツール(OpenAI、Anthropic、Perplexity など)がサイトを閲覧し、どのページにアクセスしているかを確認できます。
生 SQL による同等の処理
-- human pageviews only
SELECT count() AS human_pageviews
FROM events
WHERE event = '$pageview'
AND NOT isLikelyBot(coalesce(nullIf(properties.$raw_user_agent, ''), properties.$user_agent))
-- top bots by hits
SELECT
getBotName(coalesce(nullIf(properties.$raw_user_agent, ''), properties.$user_agent)) AS bot,
getBotOperator(coalesce(nullIf(properties.$raw_user_agent, ''), properties.$user_agent)) AS operator,
count() AS hits
FROM events
WHERE event = '$pageview'
AND isLikelyBot(coalesce(nullIf(properties.$raw_user_agent, ''), properties.$user_agent))
GROUP BY bot, operator
ORDER BY hits DESC
PostHog がまだ認識していないボットを追加する
組み込みリストの対象は、PostHog がすでに認識している、ユーザーエージェントを自ら申告するものだけです。あるスクレイパーがプロジェクトにとって重要なのに検出されない場合(社内の負荷テスト、パートナーとの連携、ニッチなクローラーなど)は、組み込みリストに追加されるのを待つのではなく、カスタムボットルールを追加してください。ルールは同じ分類機能を拡張するため、HogQL が実行されるすべての場所で、Is bot(isLikelyBot)、Bot name、Traffic category にルールが反映されます。
ルールは、1 つのイベントプロパティに一致します。デフォルトではユーザーエージェントですが、$ip、$lib、$host、$pathname、$current_url、$browser、$os、$browser_language、$screen_width、$screen_height、$geoip_country_code、$referrer、$referring_domain も指定できます。一致方式には、contains(大文字と小文字を区別しない部分文字列)、regex(RE2)、または cidr(IP 範囲。$ip でのみ有効)を使います。name には Bot name で報告されるラベルを設定し、必要に応じて category に ai_crawler などの組み込みカテゴリを設定して、トラフィックの種類を分類し直します。
ルールの管理方法は 3 つあります。
- 設定 UI — Settings → Environment → Custom bots。
- MCP ツール —
web-analytics-bot-rules-list、web-analytics-bot-rules-create、web-analytics-bot-rules-destroy。エージェントを介して PostHog を操作する場合は、こちらを推奨します。 - REST API —
GET/POST /api/projects/{project_id}/web_analytics_bot_rules/およびDELETE /api/projects/{project_id}/web_analytics_bot_rules/{id}/。
ルールの一覧表示はプロジェクトメンバーが実行できます。作成と削除にはプロジェクト管理者の権限が必要です(管理者のみ変更可能なチーム設定 modifiers を変更するため)。実行できないパターンを含むルールは保存時に拒否されるため、不正なルールによってプロジェクトの分類クエリが失敗することはありません。
JavaScript を実行しないボットを確認する
ほとんどのクローラーや AI エージェントは JS を実行しないため、posthog-js はそれらに対して $pageview を発行しません。つまり、クライアントサイド分析では検出できません。測定するには、プロジェクトでサーバーアクセスログを $raw_user_agent を含む $http_log イベントとして転送する必要があります。「GPTBot がクロールしていると分かっているのに、なぜ表示されないのか」と聞かれた場合、ほとんどの原因は $http_log が取り込まれていないことです。ボットのインサイトを作成する前に、サーバーサイドでのキャプチャ(Vercel logs ソース、エッジワーカー、またはキャプチャ API)を案内してください。
注意点
- ユーザーエージェントがキャプチャされている必要があります。 分類はイベントの
$raw_user_agent/$user_agentからクエリ実行時に計算されるため、過去のイベントにも適用されます。dateRange.date_fromを制限する必要はありません。必要なのはユーザーエージェントがキャプチャされていることです。ユーザーエージェントを設定しないソースからのイベントは分類できません(空の UA は以下のとおりAutomation/no_user_agentに分類されます)。 isLikelyBotは「可能性が高い」という意味です。 検出にはユーザーエージェントのヒューリスティックを使います。一部のボットは実際のブラウザーの UA を偽装し、正規のツールがボットに似たものを使うこともあります。確定的な判定ではなく、最善努力によるものとして扱ってください。- ユーザーエージェントが空の場合もボットになります。 UA のないリクエスト(サーバー間通信、設定を誤った SDK)は
Automation/no_user_agentに分類されるため、isLikelyBotはtrueを返します。 - ホストフィルターを暗黙に削除しないでください。 ユーザーの対象が 1 つのドメインに限定されている場合は、
propertiesに$hostを引き継いでください。これを省くと回答が変わります。 - ボットの定義は変化します。 検出対象のボット一覧は時間とともに変わるため、同じクエリを後日再実行すると、過去のイベントの分類結果が異なる場合があります。