⌘K でツールを切替
NETWORK · HTTP

UserAgentパーサー

ユーザーエージェント文字列からブラウザとOSを検出します。

local
user-agent-parser
§01 このツールについて

概要

User-Agent 文字列はブラウザによる自己申告で、HTTP の中でも最も信用できない フィールドの 1 つです。理由の半分はクライアントが意図的に嘘をつくことで、 もう半分は 30 年分の互換性対応の結果、どの文字列も複数のブラウザを同時に 名乗るようになったことです。

このツールはブラウザとバージョン、OS とバージョン、端末種別、そして文字列が 自動化を自己申告しているかを表示します。

使い方

  1. User-Agent 文字列を貼ります。読み込み時には自分のものが入っています。
  2. ブラウザ・OS・端末・ボット判定を読みます。

判定順そのものが問題の本体

Microsoft Edge の文字列を見てみます。

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0

Mozilla・AppleWebKit・Chrome・Safari・Edge を名乗っています。Chrome を先に 調べるパーサは Chrome と報告し、まさにこの理由で膨大な量のアクセス解析データが 間違っています。

規則は、より具体的なトークンを先に調べることです。Chrome/ より前に Edg/OPR/SamsungBrowser/。そして Safari より前に Chrome/。Chromium は Safari も名乗りますが、Safari は Chrome を名乗らないためです。

バージョン番号も具体的なトークンから取る必要があります。Edge 120 の Chrome/120.0.0.0 は Chromium のバージョンであって Edge のバージョンではなく、 両者は乖離します。

文字列の解剖

UA は、ほとんどのトークンが記述のためではなく歴史的な理由で存在していると 知れば読みやすくなります。

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
  • Mozilla/5.0 — すべてのブラウザがこれを名乗ります。1990 年代にサーバーが フレームを配信する前に「Mozilla」を確認していたため、全員が名乗り始め、 以来誰もやめられていません。
  • 括弧の中 — プラットフォームの詳細。OS 名とバージョン、CPU アーキテクチャ、 モバイルでは端末の型番です。ブラウザが今まさに削っている部分です。
  • AppleWebKit/537.36 (KHTML, like Gecko) — 2013 年以降、Chromium 全体で 537.36 に固定されています。バージョンではなく定数です。KHTML, like Gecko は さらに 2 つのエンジンとの類縁を主張しています。
  • Chrome/120.0.0.0 — Chromium のメジャーバージョン。下位の要素は意図的に ゼロにされています。
  • Safari/537.36 — WebKit のトークンと一致します。Safari を確認するコードが 動き続けるように存在しています。

有用な情報は 1〜2 個のトークンにあり、残りは互換性の堆積物です。この文字列を 「層になった主張の集合」ではなく「記述」として扱うパーサは、判定を誤ります。

端末種別の判定

端末種別はトークンから推定しますが、重要な 2 つの信号は直感に反します。

  • iPad は Mobile を送る。 iPad の UA には Mobile/15E148 が含まれるので、 Mobi の検査に一致します。iPad の検査を先に置かないと、すべてのタブレットが スマートフォンとして報告されます。
  • Android のタブレットは Mobile を含まない。 Google の規定では Mobile トークンはスマートフォンに付き、タブレットには付きません。つまり Android の タブレットは Android かつ Mobile含まないもので、これは否定条件なので 書き忘れやすい判定です。

このツールはスマートフォンのトークンより前に iPadTablet・Android で Mobile を含まないものを検査するので、タブレットはタブレットとして分類されます。

どのパーサでも直せないのは、デスクトップモードの iPad です。iPadOS 13 以降、 iPad の Safari は既定で macOS の文字列を送り、確実な識別手段は UA に含まれない navigator.maxTouchPoints だけです。タブレットの判定がアプリケーションにとって 重要なら、UA を解析するのではなくクライアント側でタッチポイント数を読んでください。

文字列は意図的に縮んでいる

ブラウザは UA が明かす情報を積極的に削っています。アクセス解析に役立つ詳細が、 同時にフィンガープリンティングを可能にするためです。

Chrome はマイナーバージョンを 0.0.0 に固定し、OS のバージョンを丸めました。 Safari は以前から固定の OS バージョンを報告しています。navigator.platform は 非推奨です。置き換えは User-Agent Client Hints(Sec-CH-UASec-CH-UA-PlatformSec-CH-UA-Mobile)で、既定では短い値の集合だけを送り、 それ以上はサーバーが要求する必要があります。

実務上の帰結は、UA パーサの精度が時間とともに落ちていくこと、そしてそれが 意図されていることです。ブラウザのメジャーバージョンと OS のファミリを持続的な 信号として扱い、それより細かいものは、いずれ届かなくなるおまけとして扱ってください。 この削減が守ろうとしている他の属性は ブラウザフィンガープリント で確認できます。

使用例

  • Chrome のシェアがあり得ない値になっている — パーサが Edg より前に Chrome を置いていないか確認します。この順序の不具合 1 つで、数パーセントの トラフィックがブラウザ間を移動します。
  • 再現手順の無いサポート報告 — 報告者の UA から得た OS とブラウザの バージョンで、通常は十分絞り込めます。
  • ログからボットを除外する — 自己申告するものは簡単です。その数値は 「下限」であって「件数」ではないと明示してください。
  • 古いブラウザ判定の点検 — UA に対して書かれたバージョン比較は既に信頼できず、 削減が進むごとに悪化します。機能判定に置き換えてください。

注意事項

アンダースコア区切りのバージョン(macOS と iOS は 10_15_7 と報告します)は ドットに正規化します。この表記の違いは UA では純粋に見た目だけで、意味を持ちません。

Unknown はどのパターンにも一致しなかったという意味で、ニッチなブラウザ・ 組み込みの WebView・HTTP クライアントライブラリ・矛盾した組み合わせを生成する 偽装拡張からの文字列では、正当な答えです。

ボット判定は botcrawlspiderslurpcurlwgetpythonheadless を探します。クライアントが何を自称しているかの記述であって、 セキュリティ対策ではありません。重要な判断はサーバー側でレート制限と チャレンジによって強制してください。UA はクライアントが選ぶ文字列です。 このサイトの API での扱いはプライバシーポリシーに書いてあります。

FAQ
文字列はどこかに送信されますか?
いいえ。判定はページ内の正規表現照合です。ブラウザから何も出ず、読み込み後はオフラインでも動きます。
Chrome の UA に Safari や Mozilla も入っているのはなぜですか?
歴史的な互換性のためです。すべてのブラウザが Mozilla/5.0 を名乗り、Chromium 系は WebKit 時代の機能判定のために Safari を名乗り、Edge・Opera・Samsung Internet はさらにその上に Chrome を名乗ります。文字列は互換性のための嘘の積み重ねで、だからパターンより判定順の方が重要です。
最近の iPad が macOS と判定されるのはなぜですか?
実際にそう送ってくるからです。iPadOS 13 以降、iPad の Safari は既定でデスクトップ版サイトを要求し、その UA は Mac と区別できません。手掛かりは maxTouchPoints で、これは UA に含まれていません。つまりどの UA パーサでも正しく判定できません。
本番の機能判定に使ってよいですか?
いけません。ブラウザではなく機能を判定してください。バージョン比較ではなく `if ('share' in navigator)` です。UA の解析はアクセス解析・サポートの一次調査・ログ分析、つまり挙動を決めるのではなくトラフィックを記述する用途のものです。
ボット判定はどのくらい信頼できますか?
正直に名乗るボットだけを捕まえます。Googlebot・curl・python-requests はいずれも自己申告します。紛れ込みたいクローラーは実在のブラウザの文字列をそのまま複製するので、UA ベースの検査では決して見えません。