【python】time.sleep()はダメ?seleniumでの待機処理テクニック

seleniumを用いたブラウザの自動操作プログラム(スクレイピングなど)を安定的に稼働させるための待機処理についてきちんと理解していますか?

本記事では、そんなseleniumにおける待機処理に関してのテクニックや知識をご紹介していきます!

こんな人におすすめ!

・待機処理がtime.sleep()しか知らない方
・スクレイピング(自動操作)を安定的に稼働させたい方

※seleniumに関する基本的な知識についてはこちらをご覧ください。

目次

なぜ待機処理は必要?

そもそもなんで待機処理が必要なのかご存知でしょうか??

ページ遷移やフォーム送信など、サーバーからの応答を待つ操作の場合はどうしても時間がかかってしまう場合があります。

実際は応答が遅れているのにも関わらず、応答が完了している前提でプログラムが進んでしまうとエラーとなってしまいます。

例えばログイン処理の場合を考えてみます。

  1. ログイン画面に遷移
  2. フォーム要素を取得

このような流れが考えられますが、ログイン画面にアクセスしたが応答が遅れた場合、フォーム要素がまだブラウザに表示されていないにも関わらず②の取得フェーズに入ってしまうとエラーを起こしてしまいます。

したがって、ちゃんとフォーム要素を取得したのを確認してから次のステップに進めるよう、適切な待機処理が必要になってきます。

待機処理の種類

seleniumを用いた待機処理には大きく分けて次の2種類が存在します。

  1. 暗黙的な待機
  2. 明示的な待機

暗黙的な待機とは、find_element()メソッドで要素を取得しようとした時の待機時間の設定のことを指します。

明示的な待機とは、DOM要素がある条件を満たすまで待機させることです。

例えば、「フォーム要素が全て現れるまで待機」「ページ内の全てのDOMが読み込まれるまで待機」などですね。

time.sleep()メソッドもこの明示的な待機に含まれます。

これらの「暗黙的な待機」と「明示的な待機」を組み合わせることで、安定したシステムを構築することができます。

このままでは抽象的なので、具体的な例を交えながら解説していきます!

暗黙的な待機

implicitly_wait()メソッドを用いることで、暗黙的な待機時間を設定できます。

# 暗黙的な定期時間を30秒に設定(デフォルトは0秒)
driver.implicitly_wait(30)

簡単です。

これを一度設定しておくだけで、これ以降のfind_element()メソッドを行う際に、要素が見つかるまで指定した時間待機させることができます。

しかし、待機時間内に要素が見つかった場合は次の処理に進んでくれます!

なので上記のコードの場合、最大待機時間は30秒となっておりますが、3秒で要素が見つかった場合の待機時間は「3秒」となります。

無駄な待機時間がないのはいいですね。

chromeを起動した後に、暗黙的な待機時間を設定してあげましょう。

# driver起動
driver = webdriver.Chrome(driver_path)

# 暗黙的な定期時間を30秒に設定(デフォルトは0秒)
driver.implicitly_wait(30)

明示的な待機

先ほどの暗黙的な待機のみでは対応しきれない部分については、ここからの明示的な待機で対応してあげます。

WebDriverWait

WebDriverWaitを使用することで、

  1. 何が
  2. どんな状態になるまで

明示的に指定して待機させることができます。

例えば、、、

何がどんな状態
指定した要素表示される
指定したテキスト表示される
ページ内のすべての要素読み込まれる
指定した要素現れる
Alert表示される
指定した要素クリックできる状態になる

などがあります。

具体的に「idが “login-btn”の要素が現れるまで待機」する処理を書いてみます。

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

# driver起動
driver = webdriver.Chrome(driver_path)

# wait作成(タイムアウトは60秒)
wait = WebDriverWait(driver=driver, timeout=60)

# ページ遷移
driver.get([適当なURL])

# id="login-btn"の要素が現れるまで待機
wait.until(EC.presence_of_element_located((By.ID, 'login-btn')))

# id="login-btn"の要素を取得
login_btn = driver.find_element(By.ID, 'login-btn')

10行目のようにまずwaitオブジェクトを作成し、wait.until…と記載(16行目)することで待機処理を行うことができます。

またこの待機処理の結果、19行目の処理を安定して行うことができます。

ここではpresence_of_element_locatedを使用しましたが、他にも様々なメソッドが存在します。

メソッド何がどんな状態
visibility_of_element_located指定した要素表示される
text_to_be_present_in_element指定したテキスト表示される
presence_of_all_elements_locatedページ内の全ての要素読み込まれる
presence_of_element_located指定した要素現れる
alert_is_presentAlert表示される
element_to_be_clickable指定した要素クリックできる状態になる

ここでは一部のみ抜粋しておりますが、他にも気になる方はこちらからご確認ください。

これらを使用することで、遅延読み込み(LazyLoad)にも対応することができます。

time.sleep()

ここまでに紹介した待機手段(implicitly_wait()、WebDriverWait)でどーーーーしても対応できなかった場合は、このtime.sleep()メソッドを使用します。

time.sleep()を使用することで、欲しい要素が表示されてようがされてなかろうが、強制的に任意の時間待機させることができます。

from time import sleep

# 強制的に10秒待機
sleep(10)

なので余分な待機時間が発生してしまう可能性があるので賢い待機方法とは言えません。

ただし!

サーバーへの負荷の調整のために使用する場合はその限りではありません。

例えば、100ページ分のスクレイピングプログラムがあるとします。

1ページあたりの処理時間が0.5秒だとすると、0.5秒おきにアクセスすることになってしまいます。

なのでもう少しインターバルを意図的に開けたい場合などは、time.sleep()メソッドを使用すると良いでしょう。

# スクレイピングしたいURLのリスト
url_list = [ ...URLのリスト... ]

# 各URLに対する処理
for url in url_list:
    # ページ遷移
    driver.get(url)

    # ...なんかしらの処理...

    # 待機(アクセス間隔調整)
    sleep(3)

まとめ

本記事では、スクレイピングなどのブラウザ自動操作を安定的に稼働させるための必須知識である待機処理についてご紹介させていただきました。

サイトによってはスクロールしないと要素が表示されない、、、なんていう曲者のページもありますが、基本的には本記事でご紹介した方法を活用できるのかと思います。

seleniumを用いてスクレイピングなどをお考えの方は是非本記事をご参考にしてください。

ご覧いただきありがとうございました!

案件、ありますか?

「メインの仕事があるけれど、週1、2日だけできる仕事ないかな、、、」

「ある程度スキルが身に付いてはきたけど、そのスキルを活用できる場が欲しい」

なんて悩みが以前はありました。

自分で仕事を探しに行くのも大事ですが、蛇の道は蛇。その道の人に頼むことで、自分だけでは見つからないような案件に携わることができます。

IT PRO パートナーズでは、簡単に無料でアカウントを登録でき、さらにはエージェントさんに希望の働き方・案件の種類を提示することでお仕事を紹介してくれます!

登録自体も非常に簡単で、「エージェントさんとの面談を希望する」という欄にチェックをするだけで、エージェントさんから直接連絡をいただくことができます。

驚くほど簡単で正直拍子抜けしてしまいました笑

もしお仕事探しに困っておりましたら、一度登録し案件を眺めてみることをおすすめします!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

勤めていた設計会社を退社し、フリーランスとして活動しています
また、趣味で主にpyhonを用いて機械学習を行なっています!
現在競艇の予測モデルの開発中です。

コメント

コメントする

目次