開発前に知りたいSeleniumのテクニック

●目次●

  1. 前書き
  2. コーディングの流れ
  3. ブラウザの開発者ツールの使い方
  4. メソッドの特徴(cssセレクタとxpath)
  5. 後書き
  6. 参考サイトリスト

1.前書き

こんにちは。2018年入社、エンジニアソリューション事業部のしまふくろうです。
現場でSeleniumという、Web画面操作を自動化するためのツールを使って、
テストの自動化をしています。

画面回りについてあまり知識のない状態から開発が始まり、
コーディングで試行錯誤しているうち、「もっと早く知っておきたかった……」
と思うことが沢山でてきたので、今回記事にまとめました。
(SeleniumについてはS.RさんのSeleniumの記事も参考になるかと思います。)

2.コーディングの流れ

基本的にSeleniumのコードは、以下の処理の繰り返しになる。※1 html要素の場所を指定 & 要素(WebElement)取得
  →要素に紐づく値を取得する
   要素に対してGUIの操作を加える 要素取得時は、以下のように、でcssセレクタや、xpathを使って場所指定をする。
(以下は、cssセレクタを使う場合のpythonのコード例。)
# 下記の構造で<a>を、cssセレクタを使って選んだ場合
# <div id="center-container">
#     <div class="link">
#         <a href='https://lab.m-field.co.jp/'>
from selenium import webdriver

element = driver.find_element_by_css_selector(
    "div#center-container div.link > a[href*='/m-field']")
“div#center-container div.link > a[href*=’/m-field’]”がcssセレクタ。
htmlの階層構造や、id、クラス名などを元に要素の場所を指定したものである。

cssセレクタの構文(開発時によく使うもの)

基本的なセレクタ記法の他、「疑似クラス」で調べるとよりコードが楽に書けるかもしれない。詳しくは※2を参照
a > ba要素の子要素bを選択直下要素のみ
a ba要素の子孫要素bを選択以下の階層中要素全て
a.ccというクラスを持つa要素を選択.クラス名 で要素種にかかわらず選択可能
a#ccというidを持つa要素を選択
a:nth-of-type(1)a要素のある階層のうち、
aと同じ種類のn番目要素を選択
nth-of-childと似ているが、
nth-of-childは別の要素も含めて数える
ac属性がdという値を持つa要素を選択…dから始まる値を持つ要素
…dを含む値を持つ要素
…dで終わる値を持つ要素

要素検索のメソッドを持つオブジェクト

  1. webdriverオブジェクト
  2. 1で取得したwebElementオブジェクト
この2種類のオブジェクトは、”find_element_by…”といった、要素取得用のメソッドを持っており、
要素指定に必要な情報(cssセレクタやxpath)をメソッドに渡すことで要素の取得ができる。
基本的に使い方は同じだが、2は呼び出しに使用したwebElementオブジェクトの、子以下の階層の要素のみ検索する、といった違いがある。 ” find_element_by …”というメソッドと、
cssセレクタ等の情報があれば要素が選べることが分かったと思う。 しかしこのcssセレクタ、ごちゃごちゃしている。
書くにしても、階層やクラス名を調べるのは結構手間だ。
そして、少しでも間違っていたら要素の取得ができないので、確認作業も気を使う。

できることなら楽をしたい。

コーディングで試行錯誤を繰り返した結果、
私個人としては、以下のような流れに落ち着いている。
  1. 操作に必要な要素をブラウザの「開発者ツール」(以降、開発者ツール)で探す
  2. 開発者ツールの機能でcssセレクタを自動生成
  3. (3で取得したセレクタが諸事情により使えない場合
    自力でセレクタを書く)※3
  4. 2,3 で作成したセレクタをコードの中で使いやすい形に書き換える
  5. 4で書き換えたセレクタで実際に要素が選択できるか開発者ツールで確認
以降では、Chromeの開発者ツールの使い方をご紹介する。
cssセレクタ自体詳しくない、という方でも、実際に試しながら理解できるので
ぜひブラウザを開きながら試していただきたい。
また、今回は主にcssセレクタに絞って話を進めるが、その理由は「余談」の項にて後述する。

※1:seleniumでどんなことができるのか?については、以下参照
  → Seleniumクイックリファレンス
※2:cssセレクタの基本的な書き方については、以下参照
  →セレクタの種類-CSSの基本 – HTMLクイックリファレンス
※3:セレクタが諸事情により使えない場合
  →サイトで使用するフレームワークなどとの兼ね合いにより、
   自動生成のセレクタでは都合が悪い場合がある。
   詳しくは「セレクタの自動作成 」の項を参照


3.ブラウザの開発者ツールの使い方

Chromeをはじめとする各種ブラウザでは、
F12キーを押すと、開発者ツール(デベロッパーツール)が表示される。
開発者ツールの表示例。

開発者ツールは様々な機能があるが、
今回は特に、Seleniumの開発で役に立った機能を紹介する。
(ブラウザによって機能等違いはあるが今回はChromeの開発者ツールの紹介となる。)
機能名
(画像は使用するタブ)
概要使い方使いどころ
①要素の検索画面上の要素をクリックすることで、html中の該当箇所を示す①矢印マークを押す
②要素をクリック
セレクタ調査の第一歩
階層構造の把握など
②セレクタの自動作成
Elementタブ
「要素の検索」で選択した要素のセレクタを自動で生成する①選んだ要素を右クリック
②”Copy”
使用するセレクタの原型となる
③セレクタから要素を1つ取得
Consoleタブ
cssセレクタを元に要素を1つ取得する
(階層構造がその場で確認できる)
Consoleタブで
セレクタを入力
階層構造の確認など
④cssセレクタから要素を複数取得
Consoleタブ
cssセレクタやxpathを元に要素を複数取得する
(該当要素をすべて取得できる)
Consoleタブで
セレクタを入力
想定外の要素を選んでいないかの確認など

①要素の検索


画面上の要素をクリックすることで、html中の該当箇所を探すことができる。

★階層構造や、クラス名などの属性を確認できる。
セレクタを書くための第一歩となる。
開発者ツールを開いた状態。
これからGoogleのロゴの要素を検索する。
カーソルを検索したい要素に乗せた状態。
クリックすると、Elementsタブが開き、
htmlソース中の該当箇所へ飛ぶ。

②セレクタの自動作成


「①要素の検索」で選んだ要素を右クリックすると、画像のようなメニューがでてくる。
これらの機能を使うと、cssセレクタやxpathを自動で生成できる。
★ セレクタを書く際に便利な機能。
(自動取得のセレクタだと冗長な場合がある。
そのためそのまま使うことは少なく、大抵省略、書き換えをして使っている)※4

※4
また、idを持つ要素を優先的に最上位にしてセレクタを作成するらしく、
idやクラスで自動採番するフレームワークなどを使っている場合など、使用の適さない場面が想定される。

自動パス取得方法
セレクタの自動取得方法。”Copy selector”はcssセレクタを、
“Copy XPath”はxpathを取得する。


③セレクタから要素を1つ取得

Consoleタブを開き、セレクタを打つとセレクタに該当する要素を一つ返す。※5
記述する際は $(“cssセレクタ”) のように記述する。

★セレクタが合っているかの確認や、簡単な階層構造の確認に使える。

※5:セレクタに該当する要素が画面上に複数あっても、最初に見つかった要素だけを返す。

cssセレクタで要素を1つ選ぶ
cssセレクタで要素を1つ選ぶ場合。
Console上で階層構造を操作できるので簡単な階層の確認などがしやすい。


④cssセレクタ、xpathから要素を複数取得

Consoleタブを開き、cssセレクタやxpathを指定して要素を複数取得できる。※6
cssセレクタで選ぶ場合は $$(“cssセレクタ”)
xpathで選ぶ場合は $x(“xpath”) のように記述する。

★指定したセレクタやxpathが複数の要素に該当し、意図しない動作につながることがあるため、
「想定外の要素が指定に該当していないか?」などの確認によく使っている。

※6
$(“cssセレクタ”)表記と異なり、要素の階層構造はコンソール上では確認ができないが、
出てきた行をクリックするとElementsタブの該当箇所に飛ぶことができる。

cssセレクタで要素を複数選ぶ
cssセレクタで要素を複数選ぶ場合。
xpathで要素を複数選ぶ
xpathで要素を複数選ぶ場合。
cssセレクタと大きく違うのは、xpathでは階層を遡る指定方法ができること。

4.メソッドの特徴(cssセレクタとxpath)

Seleniumで要素を取得するためのメソッドはいくつかある。
クラス名やidによる指定は、cssセレクタ・xpathで代用することができるが、
cssセレクタやxpathに関しては、同程度に複雑な条件指定ができるため、
あまり違いを感じないかもしれない。

ただし、私が使用を勧めるとしたら、cssセレクタだ。
というのも、xpathはクロスブラウザ対応に向いていないためである。
xpathはブラウザ毎に独自の実装をしている場合があるため、
xpathで実装した場合に、使用したブラウザによっては
動かないことがあるらしい。
参考:Why is XPath not working in IE? [closed]

ただ、階層の相対指定※7 機能は、xpathにしかなく、
動作するブラウザだけで使えばよい(クロスブラウザ対応が不要)場合などには
xpathの方が都合がよい場合もあるだろう。

※7:階層の相対指定
xpathでは、”div[@id=’sample’] // .. // .. // a” のような指定で、
階層構造の移動を盛り込んだ指定をすることができる。
(例ではdivの親の親の子要素に当たるa要素を選択)


5.あとがき

まとめ:
  • seleniumでは、cssセレクタやxpathを使って要素を取得する
  • 階層指定や、属性値指定などを使って操作対象の要素を細かく指定できる
  • ブラウザの開発者ツールには、セレクタの自動生成機能、
    作成したセレクタで値が取れるかの確認ができるコンソールなど、
    開発に便利な機能がある
私がSeleniumを使い始めた時一番大変だったのは、cssセレクタが合っているかどうかの確認でした。
当初はブラウザの開発者ツールでセレクタの確認ができるなど知らなかったもので、
よくNoSuchElementException(指定した要素が見つからない例外)を起こしていました。

開発者ツールには便利な機能が沢山あるので、すべての機能を使いこなすことは難しいかもしれません。
ただ、本記事を読み、ちょっとだけ効率的に開発できるようになる方がいらっしゃったらうれしいです。

6.参考サイトリスト

投稿者: エムシバ君

エムフィールドのイメージキャラクター えむしば君です。 気になったり、興味が湧いた記事があったら、なんでもコメントしてみてね。 コーポレートサイトの問い合わせ欄からでも大丈夫だよ。