Django Girls and Boys 備忘録

Python、Selenium、Django、java、iPhoneアプリ、Excelマクロなどで気付いたこと、覚えておきたいことなどを載せていきます。

【Python】Seleniumで「WebDriverWait」を使ったframe切替方法

ウェブページを操作する際に、frame要素を使って異なるHTMLコンテンツが埋め込まれている場合があります。

Seleniumでは、frame要素に切り替える必要がありますが、そのためにはWebDriverWaitを利用してframeが利用可能になるまで待機する方法が便利です。

 

この記事では、Seleniumを使ってframeを切り替える方法を説明します。

 

基本構文

 

 

普通の`frame`に切り替える場合も、WebDriverWaitとexpected_conditionsのframe_to_be_available_and_switch_to_itを使用します。

 

 

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

# 指定したframeが利用可能になるまで待機し、利用可能になったら切り替える
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME, "frameName")))

 

・driver:SeleniumのWebDriverオブジェクト

・10:最大待機時間(秒)
・By.NAME:frameを名前で指定する方法
・frame_to_be_available_and_switch_to_it:指定したframeが利用可能になるまで待機し、自動的に切り替える条件

 

実践例

 

 

1.Name指定でのframe切替

 

 

以下は、nameを指定してframeを切り替え、frame内の要素を操作する例です。

 

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

# WebDriverのセットアップ
driver = webdriver.Chrome()

try:
    # サンプルページを開く
    driver.get("https://example.com/frame-example")
    # frameが利用可能になるまで待機して切り替える
    WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME, "frameName")))
    # frame内の要素を操作
  element = driver.find_element(By.ID, "elementID")
    print("Frame内の要素のテキスト:", element.text)

finally:
  # WebDriverを閉じる
    driver.quit()

 

 

2.ID指定でのframe切替

 

frameをIDで指定する場合は、By.IDを使います。

WebDriverWait()の行だけを取り出した例は以下になります。

 

WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "frameID")))

 

3.frameをXPathで指定する

 

 

frameのXPathを指定して切り替える場合の例としては以下のようになります。

WebDriverWait()の行だけを取り出した例は以下になります。

 

WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//frame[@src='example.html']")))

 

 

注意点

 

 

1.正しいセレクタを選ぶ  
   frameにはIDやNAMEが設定されている場合が多いですが、それらがない場合はXPathCSS_SELECTORを使って正確に指定します。

 

2.元のコンテンツに戻る方法  
   frame内の操作を終了したら、driver.switch_to.default_content()を使って元のページコンテンツに戻ることができます。

 

driver.switch_to.default_content()

 

3.エラーハンドリング  
   指定した時間内にframeが利用可能にならない場合、TimeoutExceptionが発生します。

このエラーをキャッチして処理を続けることが重要です。

 

from selenium.common.exceptions import TimeoutException

try:
    WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "frameID")))
except TimeoutException:
    print("指定したframeが利用可能になるまでにタイムアウトしました。")

 

 

応用例:ページに複数のframeがある場合

 

 

複数のframeが存在するページでは、find_elementsで全てのframeを取得し、必要なframeを選択して切り替えることができます。

以下の例ではframes[]の中に複数のframeが入っているのでframes[1]で2つ目を取り出しています。

 

frames = driver.find_elements(By.TAG_NAME, "frame")
print(f"見つかったframeの数: {len(frames)}")

# 2番目のframeに切り替え
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(frames[1]))



まとめ

 

Seleniumでは、frameへアクセスする際にWebDriverWaitとframe_to_be_available_and_switch_to_itを組み合わせることで、frameの読み込みを待ちながらスムーズに操作を進めることができます。

この方法は、ページ内のframeが多い場合や、読み込みタイミングが不確実な場合に特に有効です。

この記事を参考に、自身のプロジェクトでframe操作を試してみてください!