「Python|Selenium|场景案例」如何定位iframe中的元素?

Table of Contents

场景描述

当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常

比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name, class_name, id或者xpath来定位<iframe></iframe>中的页面元素,会抛出NoSuchElementException异常。

解决方案

  • 如果要定位iframe中的元素,需要在定位之前将web_driver切换到对应的iframe中,就像切换tab一样。
  • 切换web_driver到iframe中,可以使用web_driver对应的.switch_to.frame(frame_reference)方法
  • 同样的,如果已经切换到iframe之后,要定位iframe之外的页面元素,需要先切换回默认的页面内容,使用.switch_to.default_content()方法
  • .switch_to.frame(frame_reference)传入的参数frame_reference可以是代表目标iframe的id或者``class的一个字符串或者是一个定位到的iframe(webelement.WebElement对象),或者是一个数值,代表切换到当前页面中指定次序的iframe。
  • switch_to.freame的help文档如下:
1""" 2Help on method frame in module selenium.webdriver.remote.switch_to: 3 4frame(frame_reference) method of selenium.webdriver.remote.switch_to.SwitchTo instance 5 Switches focus to the specified frame, by index, name, or webelement. 6 7 :Args: 8 - frame_reference: The name of the window to switch to, an integer representing the index, 9 or a webelement that is an (i)frame to switch to. 10 11 :Usage: 12 driver.switch_to.frame('frame_name') 13 driver.switch_to.frame(1) 14 driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0]) 15"""

具体代码

以CSDN的登录窗体为例,通过F12开发者模式可以看到如下页面结构:

1<iframe width="410" height="520" name="passport_iframe" 2 src="https://passport.csdn.net/account/login?from=https%3A%2F%2Fblog.csdn.net%2F&amp;iframe=true&amp;newframe=true&amp;version=loginv3" 3 style="border-radius: 8px;" frameborder="0" scrolling="no"></iframe>

我们看到这里的iframe有一个passport_iframename属性,于是可以使用如下代码切换到iframe中: 这里使用的selenium版本为3.141.0,新版本的selenium在创建web_driver对象和定位页面元素的API上有细微差异,可以参考官方文档

1from selenium import webdriver 2web_driver = webdriver.Chrome("D:/chromedriver.exe") 3web_driver.get("https://blog.csdn.net/") 4web_driver.find_element_by_class_name("toolbar-btn-loginfun").click() 5 6""" 7登录窗体已弹出, 8如果直接使用新版本API中的find_element()或者旧版本API中的find_element_by_XXXX()来定位窗体中的元素, 9就会抛出NoSuchElementException 10需要先切换到iframe中 11""" 12web_driver.switch_to_frame("passport_iframe")# selenium 4.x.x中被废弃, 需要使用.switch_to.frame("passport_iframe") 13web_driver.find_element_by_class_name("login-box-tabs-items").find_elements_by_tag_name("span")[2].click()

如果要定位原本页面的元素,记得先使用.switch_to.default_content()从iframe中切换出来

好书推荐:

好课推荐:

写文不易,如果对你有帮助的话,来一波点赞、收藏、关注吧~👇

Mastodon