当 Selenium 遇上 iframe 内嵌#document

Don’t let anyone stop you from getting what you want. ——《灵书妙探》

别让任何人阻挡你得到想要的东西。

前情提要

  Selenium 在加载页面时,默认情况下的焦点保持在顶部窗口上,顶部窗口包含其他 iframe 和框架集。当你直接使用 Xpath 或其他方式进行定位时,就会找不到元素。

解决方法

  所以当我们需要与 iframe 中的元素交互时,必须先切换到目标 iframe 元素中,才能执行进一步的操作。我们可以通过三种方式切换到 iframe。

通过 iframe 的 name 属性

1
driver.switch_to.frame("iframe_name")

通过 iframe 的 id 属性

1
driver.switch_to.frame("iframe_id")

通过 iframe 的 索引

1
2
3
4
# 第一个 iframe
driver.switch_to.frame(0)
# 第二个 iframe
driver.switch_to.frame(1)

切回主框架

1
driver.switch_to.default_content()

1
driver.switch_to.parent_frame()

  切换 iframe 的更好方法是通过 WebDriverWait 等待预期 iframe 加载完毕。

通过 iframe 的 id 属性

1
WebDriverWait(driver, 20, 0.5).until(EC.frame_to_be_available_and_switch_to_it(By.ID, "id_of_iframe"))

通过 iframe 的 name 属性

1
WebDriverWait(driver, 20, 0.5).until(EC.frame_to_be_available_and_switch_to_it((By.NAME, "name_of_iframe")))

通过 Xpath 定位 iframe

1
WebDriverWait(driver, 20, 0.5).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "xpath_of_iframe")))

通过 CSS 定位 iframe

1
WebDriverWait(driver, 20, 0.5).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "css_of_iframe")))

参考文章:
Ways to deal with #document under iframe