【selenium-UI】frame切换/窗口切换

本文详细介绍了在Selenium中如何处理被iframe或frame包含的元素,以及在新窗口出现时如何进行窗口切换。通过使用`switch_to.frame`方法进入iframe,并通过`switch_to.default_content`返回主页面。同时,对于新开窗口的情况,利用`switch_to.window`根据窗口句柄进行切换,确保自动化测试在正确的窗口进行。
摘要由CSDN通过智能技术生成

切换到frame

问题描述:

操作例子的网址:https://cdn2.byhy.net/files/selenium/sample2.html

选择的元素被包含在iframe或者frame中,我们使用正常的选择代码去获取是获取不到内容的,执行的集成器也不会报错或提示。
需要我们检查一下网页的情况,看看是不是html文件被包含在frame或iframe模块中。
例如:
在这里插入图片描述
例如这样的代码:

"""
@Project :python_selenium 
@Author : 文跃锐(yuerwen)
@University:东莞理工学院
@Time   : 2022/03/19
@File   :Auto_selenium_frame_title.py
"""
from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()

wd.get('https://cdn2.byhy.net/files/selenium/sample2.html')

# 根据 class name 选择元素,返回的是 一个列表
elements = wd.find_elements(By.CLASS_NAME, 'plant, .animal')

for element in elements:
    print(element.text)

运行结果打印内容为空白,说明没有选择到 class 属性值为 plant 和 animal 的元素。

原因:选择的元素被包含在iframe或者frame中
这个 iframe 元素非常的特殊, 在html语法中,frame 元素 或者iframe元素的内部 会包含一个 被嵌入的 另一份html文档。

解决方案:
使用 WebDriver 对象的 switch_to 属性,像这样

wd.switch_to.frame(frame_reference)

其中, frame_reference 可以是 frame 元素的属性 name 或者 ID 。
例如:

wd.switch_to.frame('frame1')
wd.switch_to.frame('innerFrame')

比如这里,就可以填写 iframe元素的id ‘frame1’ 或者 name属性值 ‘innerFrame’。

也可以填写frame 所对应的 WebElement 对象。

我们可以根据frame的元素位置或者属性特性,使用find系列的方法,选择到该元素,得到对应的WebElement对象

比如,这里就可以写

wd.switch_to.frame(wd.find_element(By.TAG_NAME, "iframe"))

然后,就可以进行后续操作frame里面的元素了。

上面的例子的正确代码如下

"""
@Project :python_selenium 
@Author : 文跃锐(yuerwen)
@University:东莞理工学院
@Time   : 2022/03/19
@File   :Auto_selenium_frame_title.py
"""
from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()

wd.get('https://cdn2.byhy.net/files/selenium/sample2.html')


# 先根据name属性值 'innerFrame',切换到iframe中
wd.switch_to.frame('innerFrame')

# 根据 class name 选择元素,返回的是 一个列表
elements = wd.find_elements(By.CLASS_NAME, 'plant')

for element in elements:
    print(element.text)

如果我们已经切换到某个iframe里面进行操作了,那么后续选择和操作界面元素 就都是在这个frame里面进行的。

这时候,如果我们又需要操作 主html(我们把最外部的html称之为主html) 里面的元素了呢?

怎么切换回原来的主html呢?

很简单,写如下代码即可

wd.switch_to.default_content()

例如,在上面 代码 操作完 frame里面的元素后, 需要 点击 主html 里面的按钮,就可以这样写

"""
@Project :python_selenium 
@Author : 文跃锐(yuerwen)
@University:东莞理工学院
@Time   : 2022/03/19
@File   :Auto_selenium_frame_title.py
"""
from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()

wd.get('https://cdn2.byhy.net/files/selenium/sample2.html')


# 先根据name属性值 'innerFrame',切换到iframe中
wd.switch_to.frame('innerFrame')

# 根据 class name 选择元素,返回的是 一个列表
elements = wd.find_elements(By.CLASS_NAME, 'plant')

for element in elements:
    print(element.text)

# 切换回 最外部的 HTML 中
wd.switch_to.default_content()

# 然后再 选择操作 外部的 HTML 中 的元素
wd.find_element_by_id('outerbutton').click()

wd.quit()


切换新窗口

问题描述:

在网页上操作的时候,我们经常遇到,点击一个链接 或者 按钮,就会打开一个 新窗口 。

如果我们用Selenium写自动化程序 在新窗口里面 打开一个新网址, 并且去自动化操作新窗口里面的元素,会有什么问题呢?

问题就在于,即使新窗口打开了, 这时候,我们的 WebDriver对象对应的 还是老窗口,自动化操作也还是在老窗口进行,

有问题的代码验证如下:

"""
@Project :python_selenium 
@Author : 文跃锐(yuerwen)
@University:东莞理工学院
@Time   : 2022/03/19
@File   :Auto_selenium_frame_title.py
"""
from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()
wd.implicitly_wait(10)

wd.get('https://cdn2.byhy.net/files/selenium/sample3.html')

# 点击打开新窗口的链接
link = wd.find_element(By.TAG_NAME, "a")
link.click()

# wd.title属性是当前窗口的标题栏 文本
print(wd.title)

结果:
运行完程序后,最后一行 打印当前窗口的标题栏 文本, 输出内容是

白月黑羽测试网页3

说明, 我们的 WebDriver对象指向的还是老窗口,否则的话,运行结果就应该新窗口的标题栏 “微软Bing搜索”

如果我们要到新的窗口里面操作,该怎么做呢?

可以使用Webdriver对象的switch_to属性的 window方法,如下所示:

wd.switch_to.window(handle)

其中,参数handle需要传入什么呢?

WebDriver对象有window_handles 属性,这是一个列表对象, 里面包括了当前浏览器里面所有的窗口句柄。

所谓句柄,大家可以想象成对应网页窗口的一个ID,

解决问题的思想:
我们依次获取 wd.window_handles 里面的所有 句柄 对象, 并且调用 wd.switch_to.window(handle) 方法,切入到每个窗口,

然后检查里面该窗口对象的属性(可以是标题栏,地址栏),判断是不是我们要操作的那个窗口,如果是,就跳出循环。

那么我们就可以通过 类似下面的代码:

for handle in wd.window_handles:
    # 先切换到该窗口
    wd.switch_to.window(handle)
    # 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口
    if 'Bing' in wd.title:
        # 如果是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环,
        break

解决的代码如下:

"""
@Project :python_selenium 
@Author : 文跃锐(yuerwen)
@University:东莞理工学院
@Time   : 2022/03/19
@File   :Auto_selenium_frame_title.py
"""
from selenium import webdriver
from selenium.webdriver.common.by import By

webDriver = webdriver.Chrome()

# 创建等待时间
webDriver.implicitly_wait(5)

# 打开浏览器
webDriver.get(r'https://cdn2.byhy.net/files/selenium/sample3.html')


## 点击打开新窗口的链接
link = webDriver.find_element(By.TAG_NAME, "a")
link.click()

# wd.title属性是当前窗口的标题栏 文本
print(webDriver.title)

handles = webDriver.window_handles
for handle in handles:
	webDriver.switch_to.window(handle)
	if '必应' in webDriver.title:
		break
# 切换成功之后的title
print(webDriver.title)
webDriver.quit()

同样的,如果我们在新窗口 操作结束后, 还要回到原来的窗口,该怎么办?

我们可以仍然使用上面的方法,依次切入窗口,然后根据 标题栏 之类的属性值判断。

还有更省事的方法。

因为我们一开始就在 原来的窗口里面,我们知道 进入新窗口操作完后,还要回来,可以事先 保存该老窗口的 句柄,使用如下方法

# mainWindow 变量保存当前窗口的句柄
mainWindow = wd.current_window_handle

切换到新窗口操作完后,就可以直接像下面这样,将driver对应的对象返回到原来的窗口

#通过前面保存的老窗口的句柄,自己切换到老窗口
wd.switch_to.window(mainWindow)

解决的代码如下:

"""
@Project :python_selenium 
@Author : 文跃锐(yuerwen)
@University:东莞理工学院
@Time   : 2022/03/19
@File   :Auto_selenium_frame_title.py
"""
from selenium import webdriver
from selenium.webdriver.common.by import By

webDriver = webdriver.Chrome()

# 创建等待时间
webDriver.implicitly_wait(5)

# 打开浏览器
webDriver.get(r'https://cdn2.byhy.net/files/selenium/sample3.html')


## 点击打开新窗口的链接
link = webDriver.find_element(By.TAG_NAME, "a")
link.click()

# wd.title属性是当前窗口的标题栏 文本
print(webDriver.title)

# mainWindow 变量保存当前窗口的句柄
mainWindow = webDriver.current_window_handle

handles = webDriver.window_handles
for handle in handles:
	webDriver.switch_to.window(handle)
	if '必应' in webDriver.title:
		break
		
# 切换成功之后的title
print(webDriver.title)

#通过前面保存的老窗口的句柄,自己切换到老窗口
webDriver.switch_to.window(mainWindow)

print(webDriver.title)

webDriver.quit()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yuerwen_python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值