ウェブページを操作する際に、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が利用可能になるまで待機し、自動的に切り替える条件
以下は、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()
frameをIDで指定する場合は、By.IDを使います。
WebDriverWait()の行だけを取り出した例は以下になります。
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "frameID")))
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が設定されている場合が多いですが、それらがない場合はXPathやCSS_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が存在するページでは、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操作を試してみてください!