【Selenium】TimeoutExceptionへの対応方法

【Selenium】TimeoutExceptionへの対応方法 プログラミング

「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エラーの対応方法を説明しました。

タイトルとURLをコピーしました