selenium使用で詰まった時に確認したいポイントまとめ

Python

スクリーンショットを確認してみる

自分の場合、headlessモードでありがちなのですが、想定した画面が表示されていないということがあります。これは、headlessでGUIで確認することが出来ないので難しいのですが、そのような場合は、スクリーンショットを撮って確認してみましょう。

スクリーンショット取得

スクリーンショットの撮り方は以下の方法です。関数が用意されているので、とても簡単にスクリーンショットを撮ることが可能です。

driver.save_screenshot(FILENAME)

オプションで画面サイズを指定

これもheadlessモードで要注意なのですが、webdriverのオプションで全画面表示する為のオプションで--start-maximizedを指定しがちなのですが、headlessモードだと画面が無い為、このオプションが有効ではありません。なので、以下のようにwindow-sizeで画面サイズを指定してあげないと、レスポンシブルデザインでスマホ用の画面が表示されてしまっているなんてことが、よくあります。

options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--window-size=1920,1080')

ソースコードを確認してみる

seleniumで実際に動かしてみて、想定している動きと違ってしまったら、まずはページのソースコードがselenium以外で見たものと合っているかどうか確認してみましょう。

ページ全体のソースコード取得

まずは、ページ全体のソースコードの取得方法です。以下の方法でソースコードを見ることが出来ます。

print(driver.page_source)

Element内のソースコードのみ取得

ページ全体のソースコードまでは必要なく、一部分のみのソースコードを確認したい場合は、以下の方法でElement内だけのソースコードを拾うことが出来ます。

element = driver.find_element(By.ID, 'something')
print(element.get_attribute('innerHTML'))

テキストからElementを取得する

seleniumで一番使用すると言っても過言ではないfind_elementですが、時々、取得するのが難しい要素があります。そんな場合は以下の方法を試してみましょう。

リンクの場合、リンクテキストから判定

リンクの場合は、LINT_TEXTというものが用意されている為、それを使用すると完全一致するものを取得することが出来ます。

element = driver.find_element(By.LINK_TEXT, 'ログイン')

ElementのinnerTextから判定

例えば、ログインボタンにidやclass名もついてないようなボタンがあるします。そのような場合は、ボタンに使われているテキストからElementを取得します。

element = driver.find_element(By.XPATH, '//button[contains(text(), "ログイン")]')

この方法は、containsなので、完全一致ではなく部分一致で取得出来ることも特徴で、非常に使いやすいです。

属性からElementを取得する

上記のテキストからElementを取得する場合と同じく、属性からElementを取得したい場合があります。その場合は、XPathが便利です。@マークで属性のタイプを指定出来るので、あとはその属性の値を指定してあげるだけでElementの取得が出来ます。

element = driver.find_element(By.XPATH, '//button[@data-testid="something"]')

Elementの存在チェック

Element取得時に良く発生するのが、NoSuchElementException: Message: no such element: Unable to locate elementです。これは、Elementが見つからないということなのですが、見つからなくても、そのまま実行を続けたい場合があります。

その場合は、try ~ exceptのexceptでpassしてあげても良いのですが、Elementの存在チェックをしてから、Elementを取得する方法を使っても良いのではないかと思います。

ただし、exists()のような関数は存在していない為、以下のようにElementのlist取得を利用して存在のチェックを行います

elements = driver.find_elements(By.CLASS_NAME, 'something')
if elements:
  ・・・

find_elementsを使用すると、結果はlist形式になるので、listが空か否かで存在チェックの代わりにすることが出来るようです。

ボタンのクリックはclick関数ではなく、javascriptでクリックする

ボタンをクリックする際は、click()という関数が用意されています。

しかし、この関数を使用すると、ElementClickInterceptedException: Message: element click interceptedのエラーが発生しがちです。

このエラーはElementが画面外にある場合に発生してしまいます。なので、画面サイズによって引き起こすエラーとなる為、画面サイズを気にせずクリック出来るようにしておいた方が安全です。

そこで使用するのが、execute_scriptの用途でも紹介したjavascriptを使用する方法です。これを使用することが画面外にある要素でもクリックすることが可能です。

element = driver.find_element(By.ID, 'something')
driver.execute_script('arguments[0].click();', element)

新しいタブにフォーカスを当てる

リンクで新規タブを開く場合があります。その時に新規タブの方を見に行きたい時には、そちらのタブにフォーカスを切り替えてあげないといけません。

driver.window_handlesでタブの数が分かるので、一番新規であれば、-1を指定しといてあげると良いかと思います。

driver.switch_to.window(driver.window_handles[-1])

最後に

いかがでしたか?自分がハマりがちな使用方法をまとめてみました。

これら以外にも使用していると、色々な問題の出てくるSeleniumなので、今後も追記していければと思います。

コメントを残す