Webブラウザの自動操作を効率化するSeleniumにおいて、目的の要素を正確に特定することは、テストの安定性を左右する極めて重要な工程です。
近年、Webサイトの構造は複雑化しており、単一のIDやクラス名だけでは要素を一意に特定できないケースが増えています。
特に、動的に生成されるコンテンツや、同じ属性を共有する複数のボタンが存在する環境では、従来の単純な指定方法では限界があります。
そこで重要となるのが、複数の属性値を組み合わせて要素を特定するテクニックです。
本記事では、CSSセレクタとXPathという2つの強力な手法を用い、複数の属性を論理的に組み合わせて要素を絞り込む具体的な方法について解説します。
なぜ属性値の組み合わせが必要なのか
現代のフロントエンド開発においては、ReactやVue.jsといったフレームワークが広く普及しています。
これらのフレームワークでは、要素のIDが実行のたびに動的に変更されたり、同じスタイルを適用するために同一のクラス名が多用されたりすることが一般的です。
このような状況下で単一の属性のみに依存したロケータを作成すると、意図しない要素を操作してしまったり、要素が見つからずにテストが失敗したりする原因になります。
複数の属性(例えば、name、type、data-testidなど)を組み合わせることで、特定の要素をピンポイントで指し示すことが可能になります。
これにより、Webサイトのレイアウトが多少変更されたとしても、自動化スクリプトの保守性と堅牢性を大幅に向上させることができます。
CSSセレクタによる属性の組み合わせ指定
CSSセレクタは、ブラウザがレンダリング時に要素を特定するために使用する仕組みであり、Seleniumにおいても非常に高速に動作します。
複数の属性を組み合わせて指定する場合、属性セレクタを連結させて記述します。
基本の組み合わせ構文
CSSセレクタで複数の属性を指定するには、属性を指定する角括弧([])を連続して記述します。
例えば、type="text"かつname="username"を持つinput要素を特定する場合は、以下のようになります。
# 複数の属性を組み合わせたCSSセレクタの例
element = driver.find_element(By.CSS_SELECTOR, 'input[type="text"][name="username"]')
この記述方法は、「かつ(AND条件)」を意味しており、指定したすべての属性に合致する要素のみが抽出されます。
クラス名やタグ名との組み合わせ
属性値だけでなく、クラス名やタグ名と組み合わせることも可能です。
btnというクラスを持ち、かつdata-action="submit"という属性を持つボタンを特定する場合、ドット(.)と角括弧を組み合わせて表現します。
# クラス名とカスタム属性を組み合わせる
submit_button = driver.find_element(By.CSS_SELECTOR, 'button.btn[data-action="submit"]')
このように記述することで、ページ内に複数の「submit」属性があっても、特定のクラスを持つボタンだけに絞り込むことができます。
部分一致を活用した組み合わせ
CSSセレクタでは、属性値の一部が一致する場合の指定も可能です。
idの一部に「user_」が含まれ、かつclassが「active」である要素を探す場合は、アスタリスク(*)を利用します。
# IDの部分一致とクラス名の組み合わせ
active_user_element = driver.find_element(By.CSS_SELECTOR, '[id*="user_"].active')
前方一致(^=)や後方一致($=)も活用することで、より柔軟な要素特定が可能になります。
XPathによる高度な組み合わせ条件
XPathは、XML文書の構造を辿るための言語であり、CSSセレクタよりも複雑な条件分岐を得意としています。
特に「OR条件」や「テキストノードとの組み合わせ」が必要な場合には、XPathが非常に有用です。
論理演算子「and」の使用
XPathで複数の属性を組み合わせる際は、and演算子を使用します。
以下の例は、class属性とtitle属性の両方を満たす要素を取得する方法です。
# and演算子を用いたXPathの指定
element = driver.find_element(By.XPATH, "//div[@class='container' and @title='main_content']")
CSSセレクタと同様に、複数の条件を重ねることで特定精度を高めることができます。
論理演算子「or」による柔軟な指定
CSSセレクタでは困難な指定の一つに、「いずれかの属性を持っていれば良い」というOR条件があります。
XPathを使えば、or演算子を用いることで簡単に実現できます。
# or演算子を用いたXPathの指定
# idが'login'、またはnameが'submit'のいずれかに合致する要素を取得
element = driver.find_element(By.XPATH, "//*[@id='login' or @name='submit']")
これは、A/Bテストなどで要素の属性が動的に切り替わるサイトを自動化する際に非常に効果的です。
contains関数と属性の組み合わせ
XPathの強力な機能の一つに、特定の文字列が含まれているかを判定するcontains()関数があります。
これと他の属性指定を組み合わせることで、非常に強力なロケータを作成できます。
# type属性が'button'で、かつテキストに'送信'が含まれる要素を特定
submit_btn = driver.find_element(By.XPATH, "//button[@type='submit' and contains(text(), '送信')]")
属性値だけでなく画面に表示されている文字列も条件に加えることで、ユーザーの視覚に近い形での要素特定が可能になります。
CSSセレクタとXPathの比較
要素特定において、どちらの手法を選択すべきかは状況によります。
以下の表に、属性を組み合わせる際のそれぞれの特徴をまとめました。
| 特徴 | CSSセレクタ | XPath |
|---|---|---|
| 記述の簡潔さ | 非常に簡潔 | やや冗長 |
| 実行速度 | 高速 | 標準的(CSSよりは遅い) |
| 論理演算(AND) | 容易(連結するだけ) | 容易(andを使用) |
| 論理演算(OR) | カンマ区切りで可能だが限定的 | 柔軟に指定可能 |
| テキスト検索 | 不可能 | 可能 |
基本的には、読みやすさとパフォーマンスに優れるCSSセレクタを優先的に検討するのが定石です。
しかし、親要素を遡る必要がある場合や、テキスト内容を条件に含める高度な組み合わせが必要な場合には、迷わずXPathを選択しましょう。
実践的なコード例:多機能な検索フォームの操作
ここでは、複数の属性を組み合わせて特定の入力を操作する、より実戦に近いコード例を紹介します。
例として、複数の検索カテゴリが存在するWebページで、「ニュース」カテゴリのキーワード入力欄を特定するケースを想定します。
from selenium import webdriver
from selenium.webdriver.common.by import By
# ブラウザの起動
driver = webdriver.Chrome()
# サンプルサイトへのアクセス
driver.get("https://example.com/search")
# CSSセレクタ:name属性とplaceholder属性を組み合わせて特定
search_input = driver.find_element(
By.CSS_SELECTOR,
"input[name='q'][placeholder='キーワードを入力してください']"
)
search_input.send_keys("Selenium 最新情報")
# XPath:特定の属性を持ち、かつ隣接するラベルが'ニュース'であるボタンを特定
# (高度な組み合わせ:属性と構造の利用)
news_filter = driver.find_element(
By.XPATH,
"//input[@type='radio' and @value='news' and not(@disabled)]"
)
news_filter.click()
print("要素の特定と操作に成功しました。")
driver.quit()
要素の特定と操作に成功しました。
このコードでは、not(@disabled)のように、属性が存在しないこと(または無効化されていないこと)を条件に加えるテクニックも使用しています。
これにより、同じHTML構造のまま「グレーアウトされているボタン」を避け、「クリック可能なボタン」だけを正確に取得することが可能になります。
保守性の高いロケータを作るためのポイント
属性を組み合わせる際に注意すべきなのは、あまりに多くの条件を詰め込みすぎないことです。
条件が多すぎると、Webサイトの軽微な変更(例えば、補助的なクラス名の追加など)でもロケータが壊れてしまう可能性があります。
要素を一意に特定するために必要最低限かつ、意味的に変化しにくい属性を選択しましょう。
具体的には、スタイルに関するクラス名よりも、name、value、あるいはテスト専用に付与されたdata-testidなどを優先的に組み合わせるのが理想的です。
もし開発チームと協力できる環境であれば、自動テスト用のカスタム属性をHTMLに付与してもらうことが、最も安定した自動化への近道となります。
まとめ
Seleniumでの要素特定は、単一の属性から複数の属性を組み合わせる手法へとステップアップすることで、その精度が飛躍的に向上します。
CSSセレクタはシンプルさと速度を重視する場合に最適であり、XPathは複雑な条件やテキスト検索を必要とする場合に真価を発揮します。
今回解説した[attr1][attr2]というCSSの連結指定や、XPathのand、or、containsといったテクニックを適切に使い分けましょう。
Webサイトの構造に合わせて柔軟にロケータを構築できるようになれば、エラーに強くメンテナンスしやすい自動化スクリプトを作成できるはずです。
日々の開発やテスト業務において、今回ご紹介した組み合わせテクニックをぜひ実践してみてください。
