「Seleniumでエラーが出て困っている・・・」
「TimeoutExceptionが出てプログラムが途中で止まってしまう・・・」
このような場合には、この記事の内容が参考となります。
この記事では、TimeoutExceptionエラーへの対応方法を解説しています。
本記事の内容
- SeleniumにおけるTimeoutExceptionエラーとは?
- TimeoutExceptionエラーの発生原因
- TimeoutExceptionエラーの対応方法
それでは、上記に沿って解説していきます。
SeleniumにおけるTimeoutExceptionエラーとは?
Seleniumでスクレイピングをしていると、様々な状況に遭遇します。
想定通りに、スクレイピング対象のページが表示されるとは限らないのです。
ページ構成の仕様を把握できていないことは、普通にありえます。
要素自体が表示されないケースもあります。
そのような場合には、次のようなエラーが発生します。
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element:
要素が見つからないというエラーですね。
Seleniumでは、あるあるなエラーになります。
このエラーを出さないようにする方法を次の記事で解説しています。
基本的には、上記の記事の内容で対応はできます。
対応すれば、NoSuchElementExceptionエラーが出ないようにはなります。
しかし、別のエラーが出ることがあるのです。
そのエラーとは、以下のエラーになります。
selenium.common.exceptions.TimeoutException: Message:
TimeoutExceptionエラーは、要素が待機時間内に見つからなかった場合に発生します。
指定した時間をタイムアウトしたということですね。
以上、SeleniumにおけるTimeoutExceptionエラーについて説明しました。
次は、TimeoutExceptionの発生原因を説明します。
TimeoutExceptionエラーの発生原因
エラーを解消するには、その原因を理解する必要があります。
そのため、TimeoutExceptionエラーの発生原因を確認していきます。
TimeoutExceptionは、明示的な待機の場合に発生します。
明示的な待機では、WebDriverWaitを用います。
WebDriverWaitの定義は、以下。
引数timeoutの設定は、必須です。
10と設定すれば、最大で10秒は待機します。
具体的には、以下のコードです。
elem = WebDriverWait(driver, 10).until(lambda x: x.find_element(By.ID, "add_p"))
大抵の場合は、10秒もあれば要素を見つけることができます。
しかし、そもそも要素が表示されない場合もありえます。
その場合に、TimeoutExceptionエラーが発生してしまいます。
以上、TimeoutExceptionエラーの発生原因を説明しました。
次は、TimeoutExceptionエラーの対応方法を説明します。
TimeoutExceptionエラーの対応方法
TimeoutExceptionエラーは、例外です。
そのため、例外処理を行います。
「例外処理とは?」となる場合は、次の記事をご覧ください。
例外処理の対応を行った場合のコードは、以下。
例外処理を加える前のコードは、「NoSuchElementExceptionへの対応方法」に記載しています。
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.chrome import service as fs from selenium.common.exceptions import TimeoutException import traceback CHROMEDRIVER = "/usr/bin/chromedriver" URL = "http://localhost/etc/selenium/index.html" # ドライバー指定でChromeブラウザを開く chrome_service = fs.Service(executable_path=CHROMEDRIVER) driver = webdriver.Chrome(service=chrome_service) # アクセス driver.get(URL) try: # 例外が発生するかもしれない処理 elem = WebDriverWait(driver, 10).until(lambda x: x.find_element(By.ID, "add_p")) print("見つけた!!") except TimeoutException as e: print("TimeoutException") except Exception as e: print(traceback.format_exc()) # ブラウザを閉じる driver.quit()
変更したのは、以下の2箇所です。
1つ目は、import文の箇所になります。
from selenium.common.exceptions import TimeoutException import traceback
2つ目は、例外処理を行う箇所です。
try: # 例外が発生するかもしれない処理 elem = WebDriverWait(driver, 10).until(lambda x: x.find_element(By.ID, "add_p")) print("見つけた!!") except TimeoutException as e: print("TimeoutException") except Exception as e: print(traceback.format_exc())
コードの実行結果は、状況により異なります。
指定した時間(timeout=10)以内に要素が見つかった場合は、以下。
見つけた!!
指定した時間(timeout=5に変更)以内に要素が見つからなかった場合は、以下。
TimeoutException
また、TimeoutException以外の例外の場合は、エラーに沿ったメッセージが表示されます。
上記のように例外処理を行えば、処理が途中で止まることはありません。
途中で止まって欲しくないプログラムには、例外処理をした方がよいでしょう。
以上、TimeoutExceptionエラーの対応方法を説明しました。