XPath(XMLパス言語)は、HTMLおよびXMLドキュメントのドキュメントオブジェクトモデル(DOM)をナビゲートするために使用される強力なクエリ言語です。Web開発者、テスター、自動化エンジニアにとって、XPathを習得することは、Webページ上の要素を正確に特定し、相互作用するために不可欠です。Selenium、Playwright、またはその他のテストフレームワークを使用して自動化テストを開発している場合でも、Webサイトからデータを抽出している場合でも、XPathは、最も複雑なDOM構造をナビゲートするために必要な柔軟性と精度を提供します。
この包括的なガイドでは、基本的な構文から高度なテクニックまで、XPathに関するすべての知識を得ることができ、堅牢で効率的なXPath式を作成する能力を向上させます。
XPathについてさらに深く掘り下げる前に、まず、今日入手可能な最良のPostmanの代替であるApidogを紹介しましょう。Apidogは、APIドキュメント、設計、デバッグ、テスト、およびモッキングを1つの統合プラットフォームで結合しています。

Postmanとは異なり、Apidogはより直感的なインターフェース、優れたチームコラボレーション機能、およびAPI設計とテストの間のシームレスな統合を提供します。その強力なテスト機能により、ApidogはAPIの検証を容易にします。

APIとWebテストに取り組んでいる場合、Apidogの包括的なツールセットは、ワークフローを大幅に合理化し、生産性を向上させることができます。
XPathとは何ですか?
XPathは、XMLドキュメント内のノードを選択するために設計されたクエリ言語です。HTMLは特別な形式のXMLと見なすことができるため、XPathはHTMLドキュメントにも効果的に適用できます。最初は、W3C(World Wide Web Consortium)によってXSLT 1.0仕様の一部として導入され、その後、Web自動化とデータ抽出に不可欠なツールとなりました。
XPathは、要素へのパスを定義することによって、HTMLドキュメントの階層を横断することを許可するナビゲーション言語として機能します。ファイルシステム内のフォルダーをナビゲートするように。XPathが特に強力なのは、以下のような機能を備えているからです:
- 要素の階層を複数の方向でナビゲートする
- 属性、コンテンツ、または位置に基づいて要素をフィルタリングする
- 親、子、および兄弟要素に簡単にアクセスする
- データを操作し、値を比較するための組み込み関数を使用する
Web自動化におけるXPathロケーター
Selenium WebDriverのようなWeb自動化フレームワークでは、XPathロケーターはWebページ上の要素を特定するための主要な方法として機能します。CSSセレクター、ID、またはクラス名などの他のロケーターは、シンプルさとパフォーマンスのために好まれることが多いですが、XPathは複雑なシナリオで無比の柔軟性を提供します。
Web自動化におけるXPathの使用のいくつかの重要な利点は次のとおりです:
- 柔軟性:XPathは、テキストコンテンツ、親子関係、および兄弟関係に基づいて要素を特定できますが、他のロケーターでは簡単にできません。
- テキストベースの選択:XPathを使用すると、特定のテキストを含む要素を見つけることができ、動的コンテンツにとって非常に貴重です。
- 走査能力:DOMツリー内の親要素に上がる(親要素に)、子要素に下がる(子要素に)、または兄弟要素に横に移動することができます。
- 論理演算:XPathは、and、or、notなどの論理演算子をサポートしており、複雑な選択条件を可能にします。
XPathの基本事項
XPathを効果的に使用するには、その基本的なコンポーネントと構造を理解することが重要です。
1. 構文と構造
XPath式は、ドキュメントのノード階層をナビゲートするスラング(/)で区切られた一連のステップとして記述されます。各ステップは次の構成要素から成ります:
- ノードの選択(要素名またはワイルドカードなど)
- オプションの述語(角括弧で囲まれた条件)
- オプションの軸(関係の方向を指定)
基本的な構文は次のパターンに従います:
axisname::nodetest[predicate]
ここで:
axisname
は使用する関係を定義します(子、親など)nodetest
は選択するノードを特定しますpredicate
は条件に基づいて選択されたノードをフィルタリングします
2. 主要な軸とノードタイプ
XPathは、ノード間の関係を定義するためのさまざまな軸を提供します:
- child:現在のノードのすべての子供を選択します
- parent:現在のノードの親を選択します
- ancestor:すべての先祖(親、祖父など)を選択します
- descendant:すべての子孫(子供、孫など)を選択します
- sibling:兄弟(同じ親を持つノード)を選択します
- self:現在のノードを選択します
選択できるノードタイプには次のものが含まれます:
- element:HTML/XML要素
- attribute:要素属性
- text:要素内のテキストコンテンツ
- comment:コメントノード
- processing-instruction:処理命令ノード
3. 一般的な関数
XPathには、その機能を強化する多数の関数が含まれています:
- text():要素のテキストコンテンツを取得します
- contains():文字列に特定の部分文字列が含まれているかどうかをチェックします
- starts-with():文字列が特定の部分文字列で始まるかどうかをチェックします
- concat():複数の文字列を結合します
- substring():文字列の一部を抽出します
- count():ノードセット内のノードの数をカウントします
- position():ノードセット内のノードの位置を返します
- last():ノードセット内の最後のノードの位置を返します
XPathのタイプ
XPath式を構築するには、絶対的なアプローチと相対的なアプローチの2つの主要な方法があります。
絶対XPath式
絶対XPathは、ドキュメントのルートから目的の要素までの完全なパスを提供します。単一のスラング(/)で始まり、階層内のすべての要素を含みます。
例:
/html/body/div[2]/form/input[3]
利点:
- 要素への精密でユニークなパスを提供します
- 要素の特定のインスタンスをターゲットにする必要がある場合に便利です
欠点:
- 非常に壊れやすく、ページ構造が変更されると壊れやすいです
- 長くて読みづらいです
- 親要素が変更された場合は更新が必要です
相対XPath
相対XPathは、ドキュメント内の任意のポイントから始まり、ダブルスラング(//)を使用して、パスがどこからでも始められることを示します。このアプローチは、ドキュメント構造の変更に対してより柔軟で耐久性があります。
例:
//input[@id='email']
利点:
- ドキュメント構造の変更に対してより堅牢です
- 短くて読みやすいです
- 要素のユニークな属性や特性に焦点を当てます
欠点:
- 複雑なドキュメントでは、あまり特定的ではない場合があります
- 慎重に構築しないと、複数の要素に一致してしまう可能性があります
XPath構文
効果的なXPath式を構築するためには、基本的な構文要素を理解することが重要です:
基本的な構文要素:
- /(単一スラング):ルートノードから選択し、絶対パスを表します
- //(ダブルスラング):式に一致するドキュメント内のノードをどこでも選択します
- .(ドット):現在のノードを指します
- ..(ダブルドット):現在のノードの親を指します
- @(アットマーク):属性を選択します
- [](角括弧):述語(条件)を含みます
- \(アスタリスク):任意の要素ノードに一致するワイルドカード
述語
述語は、ノードの選択をフィルタリングする条件であり、角括弧で囲まれています:
//div[@class='container'] // class 'container'を持つdiv要素を選択します
//button[text()='Submit'] // テキスト 'Submit' のボタン要素を選択します
//li[position()=3] // 第3のli要素を選択します
//input[@type='text' and @required] // 必須のテキスト入力要素を選択します
XPathセレクター
XPathセレクターは、ドキュメント内のノードを選択するための基準を定義します。以下は一般的なセレクターパターンです:
要素セレクター:
//div // すべてのdiv要素を選択します
//div/p // divの直接の子であるすべてのp要素を選択します
//div//p // div内のどこにでもあるすべてのp要素を選択します
属性セレクター:
//*[@id='username'] // idが 'username' の要素を選択します
//input[@name='password'] // nameが 'password' の入力を選択します
//a[@href] // href属性を持つすべてのリンクを選択します
//img[@src='logo.png'] // 特定のsrcを持つ画像を選択します
位置セレクター:
//tr[1] // 最初のtr要素を選択します
//tr[last()] // 最後のtr要素を選択します
//tr[position()>1] // 最初以外のすべてのtr要素を選択します
//ul/li[position() mod 2 = 0] // 偶数位置にあるli要素を選択します
テキストコンテンツセレクター:
//h1[text()='Welcome'] // 正確なテキスト 'Welcome' のh1を選択します
//p[contains(text(),'important')] // '重要'という単語を含むpを選択します
//label[starts-with(text(),'User')] // 'User'で始まるラベルを選択します
XPath式
XPath式は、見つける必要がある要素に応じて単純から複雑まで幅があります。以下は、徐々に複雑化する式の例です:
単純な式:
//h1 // すべてのh1要素
//div[@class='header'] // クラス 'header' を持つすべてのdiv要素
//input[@type='submit'] // すべての送信ボタン
中間的な式:
//div[contains(@class,'product')]//span[@class='price'] // 製品div内の価格スパン
//table//tr[position() > 1] // ヘッダーを除くすべてのテーブル行
//form[.//input[@required]] // 必須入力を含むフォーム
高度な式:
//div[not(@class='hidden') and contains(@id,'section')] // 特定のIDパターンを持つ表示セクション
//ul[count(./li) > 5] // 5つ以上の項目を持つリスト
//a[contains(@href,'https') and not(contains(@class,'external'))] // 内部HTTPSリンク
XPathの軸
軸は、現在のノードからのナビゲーションの方向を定義します。軸を理解することで、より洗練された要素の選択が可能になります:
子供と子孫の軸:
child::div // ./divと同じ
descendant::p // .//pと同じ
親と先祖の軸:
parent::div // 現在のノードの親div
ancestor::form // 現在のノードの任意のform先祖
ancestor-or-self::div // 現在のノードがdivの場合、そのノードまたは任意のdiv先祖
兄弟の軸:
following-sibling::li // 現在のノードに続くすべてのli兄弟
preceding-sibling::div // 現在のノードに先行するすべてのdiv兄弟
その他の有用な軸:
following::h2 // ドキュメント内の現在のノードの後に出現するすべてのh2要素
preceding::input // 現在のノードの前に出現するすべての入力要素
self::p // 現在のノードが段落の場合、そのノードを選択します
XPath演算子
XPathは、複雑な条件を作成するためのさまざまな演算子をサポートしています:
比較演算子:
- = : 等しい
- != : 等しくない
- < : より小さい
- > : より大きい
- <= : より小さいか等しい
- >= : より大きいか等しい
論理演算子:
- and : 論理AND
- or : 論理OR
- not() : 論理NOT
算術演算子:
- + : 足し算
- - : 引き算
- \:掛け算
- div : 割り算
- mod : 余り
例:
//input[@value > 100] // 100より大きい値を持つ入力
//div[@class='item' and @id] // IDを持つクラス 'item' のdiv
//product[price > 50 and price < 100] // 価格が50と100の間の製品
//li[position() mod 2 = 1] // 奇数番号のリスト項目
XPath関数
XPathはデータ操作のための多数の組み込み関数を提供します:
文字列関数:
//a[contains(text(), 'Sign up')] // "Sign up"というテキストを含むリンク
//label[starts-with(@for, 'user')] // 'for'属性が 'user'で始まるラベル
//p[string-length(text()) > 100] // テキストが100文字を超える段落
//div[normalize-space(text())='Hello World'] // 正確なテキストを持つ div (余分な空白を無視)
数値関数:
//ul[count(li) > 5] // 項目が5つ以上のリスト
//div[round(number(@data-value)) = 42] // data-valueが42に丸められるdiv
//product[floor(price) = 99] // 価格が99に切り下げられる製品
ノードセット関数:
//tr[position() = last()] // 最後のテーブル行
//div[count(child::*) = 0] // 子要素がない空のdiv要素
//div[not(descendant::a)] // リンクを含まないdiv
XPath用デバッグコンソール
XPath式を開発およびテストする最も効果的な方法の1つは、ブラウザの開発者ツールを使用することです:
Chromeの場合:
- F12キーまたはCtrl+Shift+Iを押してDevToolsを開きます
- Consoleタブに移動します
$x("your-xpath-here")
を使用してXPath式を評価します- 結果は一致した要素の配列として表示されます
Firefoxの場合:
- F12キーまたはCtrl+Shift+Iを押してDevToolsを開きます
- Consoleタブに移動します
$x("your-xpath-here")
を使用してXPath式を評価します- 結果は一致した要素の配列として表示されます
Edgeの場合:
- F12キーまたはCtrl+Shift+Iを押してDevToolsを開きます
- Consoleタブに移動します
$x("your-xpath-here")
を使用してXPath式を評価します- 結果は一致した要素の配列として表示されます
この直接的なフィードバックループにより、対象の要素を正しく特定するまでXPath式をすばやく洗練することができます。
ヒントとベストプラクティス
1. 一般的な落とし穴を避ける
シンプルに保つ: よりシンプルなXPath式は保守が容易であり、ページ構造の変更による壊れやすさも低減します。ユニークな属性を使用して要素を直接ターゲットにする簡潔な式を目指しましょう。
絶対パスを避ける: 絶対パスは非常に壊れやすいです。パス内の任意の要素が変更された場合、XPathが壊れます。可能な限りユニークな識別子に焦点を当てて相対パスを使用してください。
具体的にする: 必要な範囲でできるだけ具体的な式を作成し、過剰にならないようにします。過剰に具体的な表現は壊れやすく、逆に具体性が不足していると意図しない要素に一致します。
述語を賢く使用する: 述語は要素をフィルタリングするのに強力ですが、あまりにも多くのネストされた述語は式を読みづらく、保守が難しくなる可能性があります。
クロスブラウザ互換性を考慮する: 一部のXPath機能はブラウザ間で異なる動作をする場合があります。すべてのターゲットブラウザで式をテストして、一貫性を確保してください。
2. パフォーマンスを最適化する
効率的なセレクターを使用する: 可能な限り、IDや他のユニークな識別子を使用してください。//*[@id='username']
式は、一般に複雑な階層セレクターよりも高速です。
//の使用を制限する: ダブルスラング演算子(//
)はドキュメント全体を検索するため、遅くなる可能性があります。要素の大まかな位置がわかっている場合は、より具体的なパスから始めてください。
要素をキャッシュする: 同じ要素と何度も相互作用する必要がある場合、XPathを使用して何度も特定するのではなく、参照を保存します。
XPath呼び出しを最小限に抑える: 各XPath評価には時間がかかります。可能な限り操作をグループ化して、ルックアップの回数を減らします。
パフォーマンスをテストする: 自動テストで遅延が発生した場合は、プロファイリングを行い、XPathクエリがボトルネックかどうかを特定してください。必要に応じて代替セレクターを考慮してください。
3. 効果的にデバッグする
ブラウザのDevToolsを使用する: ほとんどの最新のブラウザは、コンソールでXPath式を直接テストすることを許可します。これにより、式が機能するかどうかについて即座にフィードバックを得ることができます。
結果を出力する: 開発およびデバッグ中に、XPathクエリの結果をログに記録して、意図した要素を選択していることを確認してください。
コードをステップ実行する: テストフレームワーク内でブレークポイントとステップバイステップのデバッグを使用して、アプリケーションの状態とXPathの結果を検査します。
XPathにコメントを追加する: 複雑なXPath式、特に高度な機能を使用する場合やエッジケースに対処する場合は、コメントを追加して説明してください。
定期的に見直してリファクタリングする: アプリケーションが進化するにつれて、XPath式を定期的に見直し、信頼性と効率が保たれていることを確認してください。
XPathチートシート
以下はXPath式の包括的なリファレンスガイドです:
基本XPath構文:
/ // ルートノードから選択します
// // ドキュメント内のどこでもノードを選択します
. // 現在のノードを表します
.. // 現在のノードの親を表します
セレクター:
element // 指定された名前のすべての要素を選択します
@attribute // 指定された属性の値を選択します
* // すべての子要素を選択します
text() // 要素内のテキストを選択します
[predicate] // ノードをフィルタリングする条件を追加します
述語:
[name='value'] // 指定された属性値を持つノードを選択します
[position()] // 位置に基づいてノードを選択します
[last()] // 指定されたタイプの最後のノードを選択します
[contains(@attribute, 'value')] // 'value'を含む属性値を持つノードを選択します
[not(predicate)] // 条件を否定します
軸:
ancestor:: // すべての先祖を選択します
ancestor-or-self:: // 先祖と現在のノードを選択します
child:: // すべての子供を選択します
descendant:: // すべての子孫を選択します
descendant-or-self:: // 子孫と現在のノードを選択します
following:: // すべてのフォローノードを選択します
following-sibling:: // 後続の兄弟を選択します
parent:: // 親ノードを選択します
preceding:: // すべての前のノードを選択します
preceding-sibling:: // 前の兄弟を選択します
self:: // 現在のノードを選択します
演算子:
= // 等しい
!= // 等しくない
< // より小さい
<= // より小さいか等しい
> // より大きい
>= // より大きいか等しい
and // 論理AND
or // 論理OR
not // 論理NOT
関数(例):
name() // 現在のノードの名前を返します
count(nodes) // ノードセット内のノードの数を返します
concat(string1, string2) // 2つの文字列を連結します
substring(string, start, length) // 部分文字列を返します
contains(string, substr) // 文字列が部分文字列を含むかをチェックします
normalize-space(string) // 前後の空白を取り除き、スペースを圧縮します
例:
/bookstore/book // ルートの書店内のすべての書籍要素を選択します
//title[text()='XPath'] // ドキュメント内のどこにでもあるテキスト 'XPath' のタイトル要素を選択します
//*[@id='myId'] // idが'myId'の要素を選択します
/bookstore/book[position()=1] // 最初の書籍要素を選択します
//div[@class='highlight']//p // クラス 'highlight'のdiv内のp要素を選択します
//a[contains(@href, 'example.com')] // href属性に'example.com'を含むa要素を選択します
高度なXPathテクニック
動的IDおよびクラスとの作業
最新のWebフレームワークは、ページの読み込みごとに変更される動的IDおよびクラスを生成することがよくあります。以下は、これらのシナリオを処理するためのテクニックです:
// 部分属性一致を使用
//div[contains(@id, 'main-content')]
//button[starts-with(@id, 'submit-')]
//input[ends-with(@id, '-input')] // 注意:これはXPath 2.0であり、すべてのブラウザでサポートされていません
// クラス名パターンを使用
//div[contains(@class, 'btn') and contains(@class, 'primary')]
iframeの取り扱い
iframe内の要素を選択するには特別な取り扱いが必要です:
// まず、iframeを特定します
//iframe[@id='content-frame']
// 次に、Seleniumでは、XPathを使用して内部の要素を見つける前にiframeコンテキストに切り替えます
// driver.switchTo().frame(driver.findElement(By.xpath("//iframe[@id='content-frame']")));
// 切り替えた後、iframeコンテキスト内で通常のXPathを使用できます
//button[@id='submit']
要素の可視性の検出
XPath自体は要素が可視であるかどうかを直接判断できませんが、しばしば可視性を示すプロパティをチェックすることができます:
// display:noneの要素は、インラインスタイルを持っていることが多いです
//div[not(contains(@style, 'display: none'))]
// 要素はクラスによって隠されているかもしれません
//div[not(contains(@class, 'hidden'))]
// 要素にはaria-hidden属性があるかもしれません
//div[not(@aria-hidden='true')]
同じプロパティを持つ複数の要素の取り扱い
複数の要素が同じ属性またはプロパティを共有する場合、インデクシングまたはより具体的な属性を使用できます:
// クラス 'action'の第2のボタンを選択します
(//button[@class='action'])[2]
// テキストコンテンツとクラスに基づいて選択します
//button[@class='action' and contains(text(), 'Save')]
// 周囲の要素に基づいて選択します
//div[@class='card']//button[contains(text(), 'View details')]
異なるテストフレームワークにおけるXPath
Selenium WebDriver
SeleniumはXPathロケーターを直接サポートしています:
// Javaの例
WebElement element = driver.findElement(By.xpath("//button[@id='submit']"));
# Pythonの例
element = driver.find_element(By.XPATH, "//button[@id='submit']")
// JavaScriptの例
const element = await driver.findElement(By.xpath("//button[@id='submit']"));
Playwright
PlaywrightはXPathセレクターをサポートしていますが、CSSセレクターの方がパフォーマンスが良いため推奨されています:
// JavaScriptの例
const element = await page.locator('xpath=//button[@id="submit"]');
await element.click();
# Pythonの例
element = page.locator('xpath=//button[@id="submit"]')
element.click()
Cypress
Cypressはプラグインを使用してXPathをサポートしています:
// まずプラグインをインストールします:npm install -D cypress-xpath
// cypress/support/e2e.jsに追加します:
// require('cypress-xpath')
// テスト内で使用します
cy.xpath('//button[@id="submit"]').click()
実世界のXPath例
Eコマースウェブサイトの例:
// 割引のあるすべての製品を見つける
//div[@class='product'][.//span[@class='discount']]
// 特定の範囲内の価格の製品を見つける
//div[@class='product'][.//span[@class='price' and number(translate(text(), '$', '')) < 100]]
// 4つ以上の星評価の製品を見つける
//div[@class='product'][.//div[@class='rating' and @data-stars >= 4]]
フォーム検証の例:
// 必須フィールドをすべて見つける
//input[@required]
// 検証エラーのあるフィールドを見つける
//input[../span[@class='error']]
// 必須フィールドのラベルを見つける
//label[./following-sibling::input[@required] or ./input[@required]]
テーブルデータの例:
// 特定のコンテンツを持つテーブル行を見つける
//table[@id='data']//tr[td[contains(text(), 'Completed')]]
// 特定の列のヘッダーセルを見つける
//table//th[contains(text(), 'Status')]
// 特定のヘッダーと同じ列のセルを見つける
//table//th[contains(text(), 'Status')]/following-sibling::td
結論
XPathをマスターすることは、Webテスト自動化やデータ抽出に関与するすべての人にとって基本的なスキルです。このガイドでは、XPathの基本、構文、セレクター、およびベストプラクティスに関する深い理解を得ることができます。これらの戦略を実施することで、自動化テストプロセスを最適化し、テストの信頼性を向上させ、最も複雑なDOM構造を自信を持ってナビゲートできるようになります。
XPathの柔軟性と力は、特に単純なロケーターでは不十分な場合に、テストツールキットに欠かせないツールです。CSSセレクターは、パフォーマンスのためにしばしば好まれますが、テキストコンテンツに基づいて要素を選択したり、DOM階層を上に移動したりするなどのXPathのユニークな機能が優れた選択となるシナリオはたくさんあります。
よりシンプルな表現から始め、必要に応じてのみ複雑さを追加してください。アプリケーションが進化するにつれて、XPath式を定期的に見直して、効率的で保守可能であることを確認してください。これらのテクニックを練習し応用することで、時間の試練に耐える正確で堅牢なXPath式を作成する専門知識を身につけることができます。
テストを楽しんでください!