Seleniumでテストをしたり、マクロを作るみると、たまに ElementNotVisibleException
エラーが発生します。うまく動作するコードだった仕方とき、このようなエラーを発生させ、動作しないことがあります。理由は、AjaxなどのWebページがロードされる時間差があるからです。だからページの読み込みが完了していない状態で find_element_by_id
などで存在していないアイテムを検索しようとしたら、このようなエラーが発生する可能性しかありません。
解決方法は、ページがロードされるまで待つことです。
Seleniumは以下の二つの方法のwaitを提供します。
- Implicitly wait:決められた時間に十分待ち
- Explicitly wait:どのような条件が満足するまで待ち
Implicitly wait
Implicitly waitを10秒に設定すると、ページがロードされ、10秒待ちます。もしページの読み込みが2秒で完了した場合より待たずに次のコードを実行します。デフォルトの設定は0秒されており、一度だけ設定すればdriverを使用するすべてのコードに適用されます。
次のコードのようにgetを呼び出す前に、wait時間を10秒に設定すると、getこのページの両方がロードされるまで待ってから、 find_element_by_id
にelementを検索します。
from selenium import webdriver
driver = webdriver.Chrome("chrome path")
driver.implicitly_wait(10) # seconds
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")
Explicitly wait
Explicitly waitは、明示的にどのような条件が成立したときまで待ちます。条件が成立していなければtimeoutに設定された時間だけ最大限待ちます。
次のコードは、IDがsomeidあるelementがclickableになるまで待って、そのelementを返すコードです。 get()のコードの次にwait.until()のコードを追加してください。 wait.until()は、特定の条件が満たされるまで待って、そのelementを戻します。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome("chrome path")
driver.get("http://somedomain/url_that_delays_loading")
# wait until someid is clickable
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
まずWebDriverWaitオブジェクトを生成します。引数としてdriverとtimeoutが入ります。このオブジェクトは、再利用することができるため、グローバルにオブジェクトを作成し、その後に再利用するお勧めします。
条件を設定する方法は、 wait.until(조건)
のように引数に待つ条件を付けることになります。
上記の例では、条件に該当するのは、次のコードですが。 IDがsomeidあるelementがclickableになるまで待つことを意味しています。
EC.element_to_be_clickable((By.ID, 'someid')
次のコードのようにByを変更して、class nameやnameでelementを探すこともできます。
EC.element_to_be_clickable((By.CLASS_NAME, 'some_classname')
EC.element_to_be_clickable((By.NAME, 'some_name')
clickableが気に入らない場合は、以下のように element_to_be_clickable
を他の条件に変更することもできます。
EC.title_is(...)
EC.title_contains(...)
EC.presence_of_element_located(...)
EC.visibility_of_element_located(...)
EC.visibility_of(...)
EC.presence_of_all_elements_located(...)
EC.text_to_be_present_in_element(...)
EC.text_to_be_present_in_element_value(...)
EC.frame_to_be_available_and_switch_to_it(...)
EC.invisibility_of_element_located(...)
EC.element_to_be_clickable(...)
EC.staleness_of(...)
EC.element_to_be_selected(...)
EC.element_located_to_be_selected(...)
EC.element_selection_state_to_be(...)
EC.element_located_selection_state_to_be(...)
EC.alert_is_present(...)
すべてのコードに適用されるimplicitly waitと異なり、explicitly waitは、コードを入れた場所にだけ待ちます。
参考
Related Posts
- コードでUMLを作成する方法を、PlantUMLをご紹介します
- VSCode - PlantUMLプラグインのインストールと使用方法
- Node.js - Twitter apiでツイートする方法
- Visual Studio Codeでコードを自動整列
- MavenでJavaプロジェクトをビルドする方法
- GitLab - `pre-receive hook declined`エラーを解決する
- AMPサイトにFacebook Comments(コメント)を記入する
- Desktop AMPのバージョンのAdsense適用する
- GoDaddyは -> NameCheapドメイン移転する
- Selenium - ページの読み込みが完了するまで待つ(python)
- Sublime Text3でCTagsを使用する方法
- IntelliJでスカラーインストールして使用する
- NginxでReactを展開する方法
- Ubuntuの18.04 - NVIDIAドライバをインストールする方法
- Plum 84 keyboardレビュー