切换到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()