python3+selenium4实现切换窗口与iframe的方法
作者:Tester_谜城 发布时间:2022-08-08 16:34:16
在自动化测试过程中,有时后会遇到元素定位方式没有问题,但是依旧抛出无法找到元素的异常的问题,通常情况下,如果元素定位没有问题,但还是无法找到元素,则可能是由于当前焦点不在指定页面或iframe导致的,以下将对两种情况分别进行说明
1、切换窗口
比如我们现在有这样一个需求,进入百度首页后,点击新闻,然后在新闻页面的搜索框输入selenium
而使用selenium要如何实现呢,在对selenium不是很熟悉的情况下,仅仅学习了之前的内容,写出的代码就可能会抛出找不到贴吧搜索输入框元素异常,示例代码如下
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
driver.find_element(By.LINK_TEXT, '新闻').click() # 点击新闻
driver.find_element(By.ID, 'ww').send_keys('selenium') # 在新闻首页搜索框输入selenium
driver.quit()
代码看起来没什么问题,打开百度首页,点击贴吧,然后在贴吧登录页面点击立即注册,元素定位也没错,但是执行就会抛出异常,无法找到贴吧的输入框元素
造成此错误的原因是因为点击新闻之后,又打开了一个新的窗口,此时打开的窗口有百度首页和新闻页,而selenium不知道我们需不需要切换窗口,所以不会自动给我们切换窗口,需要手动进行窗口的切换
而要实现窗口的切换,则需要用到获取浏览器句柄以及窗口切换的方法
1.1、获取句柄
句柄是当前浏览器窗口或选项卡的一个类似id一样的唯一标识,可以用来判断当前窗口或选项卡是否在指定的窗口,获取句柄的方法如下:
获取当前页面句柄
driver.current_window_handle
获取当前所有存在的窗口句柄,多个句柄以列表方式存储
driver.window_handles
通常的,我们只需要使用当前窗口句柄与所有窗口句柄列表进行对比,然后使用窗口切换的方法,就可以完成窗口的切换
1.2、切换窗口
要完成窗口切换,需要使用方法switch_to.window(),完成新闻页输入selenium操作完整成功的示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
driver.find_element(By.LINK_TEXT, '新闻').click() # 点击新闻
handle = driver.current_window_handle # 获取当前窗口句柄
handles = driver.window_handles # 获取所有窗口句柄
for window_handle in handles: # 循环比较句柄
if window_handle != handle: # 如果窗口句柄与当前窗口句柄不一致,则切换到该窗口
driver.switch_to.window(window_handle)
driver.find_element(By.ID, 'ww').send_keys('selenium') # 在新闻首页搜索框输入selenium
time.sleep(2)
driver.quit()
以上代码只适用于两个窗口的切换,如果同时打开更多窗口,使用上述代码只能切换到列表最后一个非当前窗口,那存在多个窗口时需要如何准确的切换到指定的窗口呢,其实只需要追加一层判断即可,示例如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
driver.find_element(By.LINK_TEXT, '新闻').click() # 点击新闻
handle = driver.current_window_handle # 获取当前窗口句柄
handles = driver.window_handles # 获取所有窗口句柄
for window_handle in handles: # 循环比较句柄
if window_handle != handle: # 如果窗口句柄与当前窗口句柄不一致,则切换到该窗口
driver.switch_to.window(window_handle)
if driver.title == '百度新闻——海量中文资讯平台': # 如果切换后的窗口的title与指定的一致,结束循环
break
driver.find_element(By.ID, 'ww').send_keys('selenium') # 在新闻首页搜索框输入selenium
time.sleep(2)
driver.quit()
上述代码中添加了一层判断切换后的窗口title是否与预期一致,如果一致则跳出循环以保证多窗口切换时能够准确的切换到预期的窗口就停止切换
1.3、关闭窗口并切换回原窗口
在切换到指定窗口完成测试后,如果我们需要关闭此窗口并切换到原来的窗口,示例代码如下:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
driver.find_element(By.LINK_TEXT, '新闻').click() # 点击新闻
handle = driver.current_window_handle # 获取当前窗口句柄
handles = driver.window_handles # 获取所有窗口句柄
for window_handle in handles: # 循环比较句柄
if window_handle != handle: # 如果窗口句柄与当前窗口句柄不一致,则切换到该窗口
driver.switch_to.window(window_handle)
if driver.title == '百度新闻——海量中文资讯平台': # 如果切换后的窗口的title与指定的一致,结束循环
break
driver.find_element(By.ID, 'ww').send_keys('selenium') # 在新闻首页搜索框输入selenium
driver.close() # 关闭当前新闻窗口
driver.switch_to.window(handle) # 切换回原窗口,即百度首页
driver.find_element(By.ID, 'kw').send_keys('selenium') # 百度首页输入框输入selenium
time.sleep(2)
driver.quit()
需要注意的是,close()方法只是关闭当前所在窗口,但驱动的浏览器依旧处于等待执行状态,而quit()则会退出当前会话,无论打开了多少个窗口,均会被一次性关闭,且浏览器不再接受新的操作命令
2、切换iframe
除了打开多个窗口会导致无法找到元素之外,如果元素包含在iframe中,也会导致无法找到元素,比如现有如下元素:
<html>
<iframe src="a.html" id="frame0" name="frame1">
<input id="kw" / >
</iframe>
</html>
此时id为kw的input标签元素处于iframe中,要定位此元素,若直接使用
driver.find_element(By.ID, 'kw')
也会抛出无法找到元素的异常,那么如何实现frame的切换,从而精准定位到元素呢
2.1、切换到iframe中
selenium提供了switch_to.frame()方法用于实现frame的切换,此方法接收id、name、index以及selenium的WebElement对象用来实现切换,比如上述的代码中,要切换到iframe中,则可以使用以下代码实现:
from selenium import webdriver
driver = webdriver.Edge()
driver.switch_to.frame('frame0') # 通过id切换iframe
# driver.switch_to.frame('frame1') # 通过name切换iframe
# driver.switch_to.frame(0) # 通过index切换iframe,0代表第一个
# driver.switch_to.frame(driver.find_element_by_tag_name("iframe")) # 通过WebElement对象切换iframe
一般情况下,通过id或name即可解决大部分iframe切换的问题,如果没有这两个属性,再考虑使用index以及WebElement对象来实现
2.2、从frame中切换到主界面
在测试过程中,我们不仅会从主界面切换到iframe中,当操作完frame中的元素后,经常需要重新切换到主界面进行其他操作,切换回主页面使用方法如下:
driver.switch_to.default_content()
2.3、嵌套多层iframe的切换
有时候我们会遇到嵌套多层frame的情况,如下所示
<html>
<iframe src="a.html" id="frame1">
<iframe src="b.html" id="frame2" >
<input id="kw" / >
</iframe>
</iframe>
</html>
多层嵌套的情况下,如果要从主界面切换到第二层iframe,则需要一层一层的切换进去,即先切换到frame1,再切换到frame2,而不是直接切换进入frame2
driver.switch_to.frame("frame1")
driver.switch_to.frame("frame2")
selenium还提供了一个切换到父frame的方法,比如我们切换到frame2之后,要想切换到frame1操作,则不需要先切回主界面再切换到frame,而是使用如下方法:
driver.switch_to.parent_frame()
需要注意的是,如果当前已经是主页面,则使用此方法无效
灵活使用以上方法,则可轻松应对iframe的切换与窗口切换的问题,从此告别定位不到元素的苦恼
来源:https://blog.csdn.net/qq_18298049/article/details/117303257


猜你喜欢
- 前言:不知道有多少同学跟我一样,最初接触编程的动机就是为了自己做个游戏玩?今天要给大家分享的是一个 pygame 写的“
- 基本用法#初始化%h为空数组 %h={};#用数组初始化%h为a=>1,b=>2 %h=('a',1
- 本文实例讲述了PHP依赖注入原理与用法。分享给大家供大家参考,具体如下:引言依然是来自到喜啦的一道面试题,你知道什么是依赖注入吗?依赖注入(
- 本文实例讲述了Python中的True,False条件判断用法。分享给大家供大家参考。具体分析如下:对于有编程经验的程序员们都知道条件语句的
- 开始现在要加速学习了,大佬们有没有内推,给个推荐会vue2/vue3 + ts断言非空断言非空断言就是确定这个变量不是null或者undef
- 动态生成二级菜单树:<script>jQuery(function($) {/**********获取未处理报警信息总数****
- 1.在线定制下载echartshttps://echarts.apache.org/zh/builder.html2.创建一个django项
- tensorflow支持14种不同的类型,主要包括:实数:tf.float32 tf.float64整数:tf.int8 tf.int16
- 作为临时测试用python命令来搭建web测试是最好不过的选择了;CD切换到当前目录只需要一句python命令就迅速搭建好了简单的web服务
- Insert 和 Update假设现在你要把下面的数据插入到数据库中.ID = 3TheDate=mktime(0,0,0,8,31,200
- 使用环境:Win10 x64 Python:3.6.4 SqlServer:2008R2 因为
- 本文实例讲述了JS实现利用两个队列表示一个栈的方法。分享给大家供大家参考,具体如下:先看原理图:理清楚思路,再动笔写:<!DOCTYP
- 重装系统永远是个好办法,但有谁喜欢这么做呀:( 后来无意发现是卸载的时候没有卸载完全导致,下面给出完整的卸载MySQL 5.1的卸载方法:
- 前言你有没有经常好奇一些音乐软件的频谱特效是怎么做的,为什么做的这么好看?有没有想试试自己提取音乐频谱并可视化展现出来?今天,咱就结合上次的
- 1.将ipynd编译成tex建议将其放在桌面处理ipython nbconvert —to latex pdf.ipynb2.修改tex双击
- 本文实例讲述了Python实例方法、类方法、静态方法的区别与作用。分享给大家供大家参考,具体如下:Python中至少有三种比较常见的方法类型
- <html> <head> <title>Untitled Document</title>
- urllib中的异常处理在我们写爬虫程序时,若出现url中的错误,那么我们就无法爬取我们想要的内容,对此,我们引入了urllib中的异常处理
- 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。re 模块使 Python 语言拥有全部的正则表达式功能。
- 在大的互联网公司干技术的基本都会碰到测试、预发布、线上这种多套环境的,来实现测试和线上正式环境的隔离,这种情况下,就难免会碰到秀逗了把测试的