メインコンテンツへスキップ
SDETRole
SDETRole

学ぶ / チートシート

XPath と CSS セレクターのチートシート

Selenium、Playwright、ブラウザの DevTools で使える XPath と CSS を並べて比較します。表現できるなら CSS を使いましょう。短く、開発者にもなじみのある構文です。表示テキストでマッチさせたいときや、親・祖先要素へさかのぼりたいときは XPath を使います。

XPath 1.0(ブラウザが実装しているバージョン)、現行の Chrome・Firefox・Safari がサポートする CSS Selectors Level 4 で確認済み

基本

目的XPathCSS
タグで要素を指定(どこでも) //button button
id で指定 //*[@id='email'] #email
クラスで指定(複数のうちの 1 つ) //*[contains(concat(' ', normalize-space(@class), ' '), ' active ')] .active
直接の子 //ul/li ul > li
任意の子孫 //form//input form input
複数のセレクター(OR) //h1 | //h2 h1, h2
任意の要素 //* *

属性

目的XPathCSS
属性を持つ //button[@disabled] button[disabled]
等しい //input[@name='q'] input[name='q']
含む //a[contains(@href, 'orders')] a[href*='orders']
前方一致 //a[starts-with(@href, 'https')] a[href^='https']
後方一致 //a[substring(@href, string-length(@href) - 3) = '.pdf'] a[href$='.pdf']
2 つの条件(AND) //input[@type='text' and @required] input[type='text'][required]
いずれかの条件(OR) //input[@type='email' or @type='tel'] input[type='email'], input[type='tel']
否定 //input[not(@disabled)] input:not([disabled])
テスト ID //*[@data-testid='submit'] [data-testid='submit']

XPath 1.0 には ends-with() がありません。substring() を使う書き方が移植性のある回避策です。

テキスト(XPath のみ)

目的XPathCSS
テキスト完全一致(空白を正規化) //button[normalize-space()='Sign in'] 不可
テキストを含む //p[contains(., 'expired')] 不可
大文字・小文字を区別せずに含む //p[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'expired')] 不可
自身のテキストノードのみ //label[text()='Email'] 不可

.(文字列値)には子要素のテキストも含まれます。text() は要素自身のテキストノードにしかマッチしません。normalize-space() または . を優先しましょう。

要素の関係と軸

目的XPathCSS
親 //input[@id='email']/.. :has(> #email)
セルを含む祖先の行 //td[normalize-space()='#1043']/ancestor::tr tr:has(td[data-id='1043'])
次の兄弟要素 //label[.='Password']/following-sibling::input[1] label + input
後続のすべての兄弟要素 //h2/following-sibling::p h2 ~ p
前の兄弟要素 //button/preceding-sibling::input[1] 不可
ラベルセルの隣のセル //td[.='Diego Ramos']/following-sibling::td[1] 不可(テキストが起点のため)
特定の子要素を含む要素 //li[.//button[@aria-label='Remove']] li:has(button[aria-label='Remove'])

:has() は現行の Chrome、Edge、Safari、Firefox(121 以降)で動作します。古いブラウザや一部のツールでは使えません。

位置

目的XPathCSS
最初の子の行(1 始まり) //tbody/tr[1] tbody tr:first-child
n 番目の行 //tbody/tr[3] tbody tr:nth-child(3)
最後の行 //tbody/tr[last()] tbody tr:last-child
最後から 2 番目 //tbody/tr[last()-1] tbody tr:nth-last-child(2)
偶数行すべて //tbody/tr[position() mod 2 = 0] tbody tr:nth-child(even)
ページ全体で最初に一致する要素 (//button)[1] 不可:ツールの first() を使います

//tr[1] は「ページ上の最初の tr」ではなく「親の中で最初の tr であるすべての tr」という意味です。ページ上の最初の 1 つなら (//tr)[1] を使います。

状態の疑似クラス(CSS)

目的XPathCSS
チェック済みのチェックボックス・ラジオ //input[@checked] (initial state only) input:checked
無効 //button[@disabled] button:disabled
必須項目 //input[@required] input:required
空の要素 //td[not(node())] td:empty

XPath は HTML に書かれたとおりの属性を読むため、ユーザーがチェックを入れても @checked は変わりません。CSS の :checked は現在の状態に追従します。

DevTools で試す

やりたいことコード
CSS、すべての一致(Console) $$('tbody tr')
XPath、すべての一致(Console) $x("//td[.='Mei Lin']")
Elements パネルで検索 Ctrl+F / Cmd+F, then type a selector or XPath
一致数を数える $$('tbody tr').length

練習してさらに学ぶ

その他のチートシート

キーワードを入力すると SDETRole 全体を検索できます。

Pagefind による全文検索 · ブラウザ内で動作します 検索ページを開く →