自動化無しに生活無し

WEBとかAIとかLinux関係をひたすら書く備忘録系ブログ

【Selenium X Python】フォーム入力やクリックをする時は明示的な待機をする【Webdriverwait】

thumbnail

Seleniumでブラウザ操作の自動化をする時、クリックやフォーム入力などは頻繁に行われる。

だが、それがもしtimeモジュールを使用した暗黙的待機の場合、動作に再現性はなく、たびたび不具合に見舞われるだろう。

本記事では、再現性を高めるため、明示的な待機を行うWebdriverwaitを使用したクリックとフォーム入力を行う。

前提

使用しているPythonとライブラリのバージョン、ブラウザなどをまとめる。

Python 3.8.10
async-generator==1.10
attrs==22.1.0
certifi==2022.9.24
exceptiongroup==1.0.4
h11==0.14.0
idna==3.4
outcome==1.2.0
PySocks==1.7.1
selenium==4.6.1
sniffio==1.3.0
sortedcontainers==2.4.0
trio==0.22.0
trio-websocket==0.9.2
urllib3==1.26.13
wsproto==1.2.0
Mozilla Firefox 107.0

ちなみに、geckodriverは下記の方法でDL・インストールができる。

Ubuntu、WindowsにSeleniumで使用するFirefox用のgeckodriverをインストールする【Python】

普通のキー入力

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

from selenium.webdriver.common.by import By

URL     = "https://noauto-nolife.com/"

driver  = webdriver.Firefox()
driver.get(URL)

search  = driver.find_element(By.ID, "search")

search.send_keys("selenium")

要素を取得して、send_keysでキーを入力する。

しかし、これではレンダリングに遅れが生じると、失敗してしまう。

そこで、要素の取得がきちんとできるよう、待ち時間を指定する。

暗黙的な待機と明示的な待機の違い

暗黙的待機

Seleniumは要素を抜き取って、その要素に対してクリックしたりキーを入力したりする事ができる。

暗黙的な待機は、timeモジュールを使うことで、一定時間待機した後、キー入力やクリックをすることである。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

from selenium.webdriver.common.by import By


import time


URL     = "https://noauto-nolife.com/"

driver  = webdriver.Firefox()
driver.get(URL)

#暗黙的な待機(これではページが早くロードされても、遅くロードされても必ず3秒待つことになる。)
time.sleep(3)

search  = driver.find_element(By.ID, "search")

#暗黙的な待機
time.sleep(3)

search.send_keys("selenium")

だが、これだとレンダリングが3秒よりも早く終わった場合でも3秒待たないといけない。

これではブラウザの操作効率が悪い。だから、次の明示的な待機を利用する。

明示的待機

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions


URL     = "https://noauto-nolife.com/"

driver  = webdriver.Firefox()
driver.get(URL)

# 最大で10秒待つ
wait    = WebDriverWait(driver,10)

# id="search"が表示されるまで最大で10秒待つ
search  = wait.until( expected_conditions.visibility_of_element_located((By.ID, "search")) )

# search に "selenium" と入力
search.send_keys("selenium")

# 検索結果(1番目)が表示されるまで待つ
search_link = wait.until( expected_conditions.visibility_of_element_located((By.XPATH, '//div[@id="search_result"]/li[1]')) )

# クリックする
search_link.click()

結論

Seleniumでは画面外にある要素をクリックしたりキー入力したりできないようになっている。

これはもともと画面テスト用のツールとして作られたから。

だから、存在することを確認した上でクリックしなければエラー扱いになってしまう。

この点に注意することで、再現性の高いブラウザ操作の自動化が期待できるだろう。

スポンサーリンク

シェアボタン

Twitter LINEで送る Facebook はてなブログ