【Python】iframe内の要素を取り出して実行する方法(業務自動化)

Pytyon

参考書籍

本記事は以下の書籍などを参考に実際に実装したものを記事にしております。

iframeとは

iframeとは以下のサイトイメージがあるとして、赤枠に動画や別のページを埋め込んでサイト上に表示するHTMLの技法です。

※動画埋め込みイメージ

※別サイト埋め込みイメージ

コードでいうとタグに<iframe > ~ </iframe>となってい箇所ですね。

<HTMLコード例>

<body>
  <div>
  <h2>YouTube埋め込み</h2>
  <iframe width="560" height="315" src="https://www.youtube.com/embed/3O4J6E7ERjc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</body>

seleniumを使って記事内の要素を取得する場合は、通常のやりかたではこのiframe内の値を取得することができません。つまりは言い方をかえると、iframeを除く要素しか取得できません。

<余談>
HTMLの埋め込みには大きく2つやり方があります。

1.videoタグを使ったやり方
 (特徴)
 ・幅広い拡張子の動画もHTML内に埋め込める
 ・オリジナルの動画も拡張子を気にせず埋めれる

2.iframeタグを使ったやり方
 (特徴)
 ・HTMLファイル内に、別のHTMLファイル(サイト)を表示することができる。
 ・ネット上で公開されている動画も埋め込める(youtubeなど)

iframe内の要素の取り方

イメージとしてはコマンドプロンプトやパワーシェルを使う人ならわかりやすいと思いますが、
フォルダを移動するようなイメージの操作をします。

以下にはデフォルトサイト(親サイト)となる例とiframe側サイト(子サイト)となる例のHTMLの記載と、Pythonの記載例を載せています。
※解説は別

<例:HTML1(デフォルトサイト)>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IFrameの例</title>
</head>
<body>

<h1>メインページ</h1>

<iframe id="myFrame" width="600" height="400" src="iframe_content.html" frameborder="0"></iframe>

</body>
</html>

<例:HTML2(Iframe側サイト)>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IFrameのコンテンツ</title>
</head>
<body>

<h2>IFrameのコンテンツ</h2>

<p>これはiframe内の段落です。</p>

<button id="iframeButton">クリックしてください!</button>

</body>
</html>

<Pythonコード>

from selenium import webdriver
from selenium.webdriver.common.by import By

# WebDriverを起動(適切なWebDriverをインストールし、パスを設定してください)
driver = webdriver.Chrome()

try:
    # メインページを開く
    driver.get("path/to/main_page.html")

    # iframeに切り替える
    iframe = driver.find_element(By.ID, "myFrame")
    driver.switch_to.frame(iframe)

    # これでiframe内の要素と対話できます
    iframe_heading = driver.find_element(By.XPATH, "//h2[text()='IFrameのコンテンツ']")
    print("IFrameの見出しテキスト:", iframe_heading.text)

    iframe_button = driver.find_element(By.ID, "iframeButton")
    iframe_button.click()

    # 必要に応じてメインコンテンツに切り替えることもできます
    driver.switch_to.default_content()

    # iframe外の要素に対してさらなるアクションを実行できます

finally:
    # ブラウザウィンドウを閉じる
    driver.quit()

解説

ここで、親サイトからiframeタグをIDで検索して取得しています。
※IDが埋め込まれていない場合はxpathやiframeタグ検索でもOK

 # iframeに切り替える
 iframe = driver.find_element(By.ID, "myFrame")

取得した値をもとに、子サイトにswitchしています。(フォルダを遷移するイメージ)

 driver.switch_to.frame(iframe)

ここから⇒

こっちに遷移したイメージ

そして、子サイト内の要素を取得する動きをしています。

    # これでiframe内の要素と対話できます
    iframe_heading = driver.find_element(By.XPATH, "//h2[text()='IFrameのコンテンツ']")
    print("IFrameの見出しテキスト:", iframe_heading.text)

    iframe_button = driver.find_element(By.ID, "iframeButton")
    iframe_button.click()

最後に、子サイトから親サイトに戻す処理がこちら。

# iframe外の要素に対してさらなるアクションを実行できます

こっちから⇒

こっちに遷移したイメージ

デフォルトサイト(親サイト)にiframeは1つということはありません。
場合によっては2つ以上のiframeが使われている場合があります。

その場合は、各iframeタグにIDが振られていれば楽ですが、ない場合はiframeタグ検索を使用してインデックスで指定してあげれば大丈夫です。

from selenium import webdriver
from selenium.webdriver.common.by import By

# WebDriverを起動
driver = webdriver.Chrome()

try:
    # 対象のページを開く
    driver.get("対象のページのURL")

    # すべてのiframe要素を取得
    all_iframes = driver.find_elements(By.TAG_NAME, "iframe")

    # 切り替えたいiframeのインデックス(例:2番目のiframe)
    target_iframe_index = 1

    # 特定のインデックスのiframeに切り替える
    driver.switch_to.frame(all_iframes[target_iframe_index])

    # ここでiframe内の要素にアクセスできます

    # iframe内の要素の例
    iframe_element = driver.find_element(By.ID, "iframe内の要素のID")
    print("iframe内の要素:", iframe_element.text)

    # iframeからメインページに戻る
    driver.switch_to.default_content()

    # 他の操作を実行できます

finally:
    # ブラウザウィンドウを閉じる
    driver.quit()

CM

コメント

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