XPath vs CSS セレクタ: どちらを使うべきか?
Scrapeless Agent Browser は、抽出ロジックが JavaScript 実行後のページ DOM を検査できるブラウザ実行環境を提供します。
要約
- CSS は一般的な要素や属性の関係を表すのに簡潔です。 完全な視覚パスをコピーするのではなく、安定した属性と狭いスコープを使いましょう。
- XPath は明示的な軸、述語、テキスト操作を表現できます。 抽出がツリーの関係や XML のコンテキストに依存する場合、より明確になることがあります。
- CSS の :has() は関連するコンテンツによって要素を選択できます。 CSS が親のようなコンテナを決して選択できないという古い主張は言い過ぎです。
- セレクタの移植性はエンジンに依存します。 ブラウザ API やパーサライブラリは、異なるバージョンや拡張をサポートしている場合があります。
どちらのセレクタ言語から始めるべきか?
要素名、クラス、属性の単純なクエリにはまず CSS を使い、関係を XPath の軸や述語で表した方が明確になる場合に XPath を使いましょう。XPath と CSS セレクタの最良の選択は、そのルールが実行されるエンジンで正しいノードを選択する、最も単純なルールです。
どちらの言語も欠落したソースコンテンツを修復することはできません。ページが JavaScript 実行後に商品一覧を構築する場合、元のレスポンスに対して適用されたセレクタは、構文が正しくても何も返さないことがあります。クエリスタイルを比較する前に、必要なツリーが存在することを確認してください。
The CSS セレクタ仕様 は要素マッチングを定義し、一方 XPath 1.0 はドキュメントツリーをナビゲートするための式言語を定義します。多くの抽出タスクで重なりますが、異なる操作と結果モデルを提供します。
| 要件 | CSS アプローチ | XPath アプローチ |
|---|---|---|
| タグによる要素 | 短い型セレクタ | 要素ノードテスト |
| 安定した属性 | 属性セレクタ | 属性述語 |
| 子孫関係 | 子孫コンビネータ | 子孫パス |
| 直接の子 | 子コンビネータ | 子パス |
| 祖先関係 | 関係マッチングで一部のニーズをカバー可能 | 明示的な祖先軸 |
| テキストベースの条件 | 一般的な contains-text セレクタ標準はなし | 文字列関数と述語 |
| 属性またはテキスト値 | 要素マッチ後に値を読み取る | 式で属性ノードやテキストノードを選択可能 |
コンテキストはすべてのセレクタの一部
セレクタのコンテキストは、それが評価されるツリーまたはサブツリーを決定します。同じ式でも、完全なドキュメント、商品カード、埋め込みフレームから評価されると、異なる結果を返すことがあります。その前提を抽出ルールと一緒に保存してください。
XPath は評価モデルでコンテキストノードを明示します。ドキュメントルートから始まるパスは、選択済みアイテム内部で評価される相対パスとは異なる動作をします。カードループでは、相対的な子孫クエリによって各価格を正しい商品に紐づけたままにできますが、ドキュメント全体のクエリでは別のカードのフィールドを誤って選択してしまうことがあります。
CSS も明確なスコープ指定が必要です。短いセレクタをページ全体に適用すると、意図したレコードだけでなくナビゲーションやプロモーションのコンポーネントにもマッチすることがあります。先にレコードコンテナを選択しておくと、フィールドセレクタが読みやすくなり、誤ったマッチを減らせます。
The DOM クエリ インターフェース モデル セレクターに基づく要素クエリがドキュメント構造上でどのように動作するかを定義します。ブラウザコンソールで動作した文字列が、パーサーのコールバック内でも同じ意味を持つと仮定せず、実際のクエリコンテキストを評価してください。
テキストマッチングと構造ナビゲーション
XPath は、フィールドが近くのテキストや、要素属性だけでは表現しにくい関係によって識別される場合によく役立ちます。XPath は先祖要素や兄弟要素をたどることができ、文字列に対する述語も適用できます。これらの機能は、ラベルと値のレイアウトや XML ドキュメントを扱う際に役立ちます。
テキスト条件には依然として注意が必要です。ラベルには、入れ子になった span、ノーブレークスペース、ローカライズされた表現、あるいは視覚的に非表示のテキストが含まれる場合があります。表示されるフレーズが複数の子要素から組み合わされているとき、1つのテキストノードに対する厳密な比較は失敗する可能性があります。意図された値が、直接のテキストノードなのか、結合された文字列値なのか、それともレンダリングされた視覚的なラベルなのかを定義してください。
CSS には、ブラウザー要素クエリのための一般的な「テキストを含む」擬似クラスは定義されていません。いくつかのライブラリは、見慣れた構文の拡張機能を提供していますが、それらの式は標準的な CSS として移植可能なものではありません。ライブラリの拡張機能は、別の環境にそのまま渡すのではなく、エンジンの契約の一部として扱ってください。
XPath のバージョンも異なります。後の言語バージョンの関数を使用する式は、ブラウザの XPath インターフェイスや、より前のバージョンを実装しているパーサーでは実行できない場合があります。一般的なリファレンスに載っているという理由だけで関数を選ぶのではなく、選択する前に対応しているバージョンを確認してください。
小さなセレクターの例
あなたが制御する説明用マークアップでは、各レコードが article with a data-record 属性であり、アンカーを含んでいます data-role="title"CSS の式 article[data-record] a[data-role="title"] および XPath 式 //article[@data-record]//a[@data-role='title'] 対応する子孫アンカーを記述します。マッチした要素からリンク値を読み取るか、XPath でその属性を明示的に選択します。
関係条件の場合、 article[data-record]:has(a[data-role="title"]) :has() をサポートするエンジンで、囲んでいる article 要素を選択します。XPath の述語 //article[@data-record][.//a[@data-role='title']] この単純なツリーに対して同じ条件を表現しています。これらは、特定の実在するウェブサイトのセレクターではなく、例示的な表現です。
CSS の :has() が変えるもの
CSS の :has() は、相対セレクターで記述された関連要素に基づいて、ある要素をマッチさせることを可能にします。これは有用なコンテナ選択条件を表現できるため、「CSS は下方向にしか見られない」という一括的な言い方は、現代のセレクターエンジンにとっては誤解を招きます。
たとえば、カードは指定された価格要素を含んでいるために選択されることがあります。得られるマッチは、セレクターの対象として名付けられたカードです。XPath は述語や軸を通じて関連する要件を表現できますが、正確な戻り値の型とコンテキストは依然として式に依存します。
標準だけから普遍的なサポートを推測しないでください。ブラウザ、サーバーサイドの CSS-to-XPath 変換ツール、古い組み込みエンジンでは、それぞれ異なる機能が実装されている可能性があります。セレクターをそれらの環境間で共有しなければならない場合は、サポートされている共通部分を選ぶか、同等の別々のルールを文書化してください。
関係ベースのマッチングは、セマンティックフィールド設計の代替にもなりません。価格のような子要素を持つコンテナであっても、依然として誤った商品カードである可能性があります。ノードが返されたというだけでセレクタを受け入れるのではなく、識別子と抽出された値との関係を検証してください。
ポータビリティにはドキュメントモデルが含まれる
セレクターの移植性は、構文サポートとエンジンに渡されるツリーの両方に依存します。ブラウザの HTML パーサー、XML パーサー、そして寛容なサーバーサイドの HTML パーサーは、よく似た入力から異なる構造を生成し得ます。名前空間は、XML におけるもう一つの差異の原因となります。
ブラウザのインスペクターは、スクリプトによって挿入されたノードやパーサーによる補正で追加されたノードを表示できます。レスポンスパーサーは、自身への入力と自分自身の構文解析ルールだけを見ています。結果が食い違うときは、小さな関連サブツリーを比較してください。CSS を XPath に置き換えても、ソースツリーの違いは解消されません。
フレームとシャドウツリーは、追加のクエリ境界を導入します。トップレベルのドキュメントに対する通常のクエリは、すべての埋め込みまたはカプセル化されたドキュメントを走査するものと想定すべきではありません。各ツリーに対してサポートされているアクセスモデルを使用し、そのセキュリティ境界を尊重してください。
Scrapeless Agent ブラウザー コンテンツにスクリプトが必要な場合、ブラウザー実行レイヤーを提供できます。どのドキュメントと状態を検査するかは、依然として抽出ロジックが決定します。 XPath と CSS の比較 標準および現在のエンジンのサポートと照らし合わせて評価するための追加の例を提供します。
汎用的な速度主張よりも保守性のほうが重要
メンテナが理解できる、安定した関係性を表現するセレクタを選択してください。長い絶対パスや位置に強く依存したルールは、レイアウトの変更に敏感です。意味のある属性、明示的なレコードコンテキスト、および抽出された識別子の検証を優先してください。
CSS と XPath のどちらが普遍的に高速ということはありません。エンジンの実装、コンパイル、ドキュメントサイズ、クエリ構造などが実行速度に影響します。クエリ性能が重要であれば、代表的なローカルのワークロードで計測し、ネットワークおよびレンダリング時間をセレクタ評価時間とは分けて考えてください。
- 選択したツリー内に必要なノードが存在することを確認します。
- 翻訳する英語のテキストを貼り付けてください。
- 安定した属性または明確な関係を使用してください。
- 期待される一致数と必須フィールド値を確認する。
- 存在しないフィールド、重複したラベル、およびレイアウトのバリエーションをテストします。
- メンテナンスのためにエンジンと言語に関する前提条件を記録する。
重複するカードについては、個々の値だけでなく、レコードの対応関係も検証してください。タイトルセレクタと価格セレクタはそれぞれもっともらしい結果を返せる一方で、その位置関係が対応しなくなっている場合があります。各カードの内部で抽出を行い、レコードに安定した識別子を保持しておくことで、そのようなエラーを検出できるようにします。
ブラウザーでの実行が必要な場合は、それを通じて予算を立ててください。 現在の Scrapeless プラン元のレスポンスに存在しないコンテンツをレンダリングしないことを期待して、クエリ言語を選択しないでください。
カウンター例を用いたセレクタ変更のレビュー
セレクタレビューには、ターゲットが存在しない、または繰り返されているページバリエーションを含める必要があります。商品カードにセール価格がない場合、ルールは次のカードから価格を黙って選択すべきではありません。同じラベルがナビゲーションと記事の両方に現れる場合、文脈によって結果が意図したセクションに結び付いたままになるようにする必要があります。
各意味のあるレイアウトバリエーションごとに、小さな認可されたサンプルサブツリーを保持し、期待されるレコードの同一性と値の両方を比較してください。もっともらしい文字列を返すクエリだけでは、その文字列を特定のアイテムとペアにすることに依存するデータセットに対しては不十分な証拠です。カウンター例は、単純な 1 ページでの成功したマッチよりも、そのペアリングエラーをより明確に示します。
結論
要素の明確なマッチングには CSS を、関係や値の表現をより直接的に記述できる場合には XPath を使用してください。結果を比較する前に、コンテキスト、ドキュメントの状態、およびエンジンのサポートを検証します。ページや抽出環境が変化したときにも意味が明確なセレクタを選ぶことが、長期的に有効な選択です。
必要な DOM に対してセレクタを検証する
必要なノードが実行やインタラクションの後にのみ現れる場合は、Scrapeless Agent Browser を使用してください。
今すぐ登録すると $5 の無料クレジット — クレジットカード不要.
$5 クレジットを受け取る →FAQ
Q: CSS は子孫に基づいてコンテナを選択できますか?
CSS は、エンジンが :has() をサポートしている場合、関連する要素に基づいてコンテナを選択できます。これは有用な「親」のようなマッチングのニーズをカバーしますが、すべての XPath 軸や式と同一ではありません。
Q: XPath は常に CSS より遅いのですか?
XPath が常に CSS より遅いとは限りません。パフォーマンスはエンジンとクエリに依存します。一部のサーバーサイドツールは内部的に CSS を XPath に変換するため、評価時間が重要な場合は実際の環境で同等の操作を比較してください。
Q: セレクタがインスペクタでは動作するのに、パーサでは失敗するのはなぜですか?
セレクタがパーサで失敗するのは、入力ツリーがブラウザ DOM と異なるか、エンジンがサポートする構文が異なるためです。ルールを書き換える前に、JavaScript によって構築されたコンテンツ、パースの違い、クエリコンテキスト、およびライブラリ固有の拡張機能を確認してください。
Q: プロジェクトでは 1 つのセレクタ言語だけを使うべきですか?
プロジェクトは 1 つのセレクタ言語だけを使う必要はありません。一般的なケースには一貫したスタイルを用い、例外的なフィールドには、より明確でサポートされている表現を選択してください。コンテキストと返却値に関する期待を文書化し、混在したルールでも保守しやすい状態を保ちます。