目录
- selenium里面如何处理多窗口场景
- 多个窗口识别
- 多个窗口之间切换
- selenium里面如何处理frame
- 多个frame识别
- 多个frame之间切换
多窗口处理
- 点击某些链接,会重新打开一个窗口,对于这种情况,想在新页面上操作,就得先切换窗口了。
- 获取窗口的唯一标识用句柄表示,所以只需要切换句柄,就可以在多个页面灵活操作了。
多窗口处理流程
- 先获取到当前的窗口句柄(
driver.current_window_handle) - 再获取到所有的窗口句柄(
driver.window_handles) - 判断是否是想要操作的窗口,如果是,就可以对窗口进行操作,如果不是,跳转到另外一个窗口,对另一个窗口进行操作(
driver.switch_to_winidow)
多窗口案例
- 打开百度页面
- 点击登录
- 弹框中点击“立即注册”,输入用户名和帐号
- 返回刚才的登录页,点击登录
- 输入用户名和密码,点击登录
- 首先创建一个
base.py文件用于放置公共函数
from selenium import webdriver
class Base:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(5)
def teardown(self):
self.driver.quit()
- 创建
test_window.py文件,继承 Base 类
from time import sleep
from lessons.selenium_test.base import Base
class TestWindow(Base):
def test_window(self):
self.driver.get("http://www.baidu.com")
self.driver.find_element_by_link_text("登录").click() # 点击登录
self.driver.find_element_by_link_text("立即注册").click() # 点击立即注册
"""此时弹出新的注册窗口,需要跳转到新窗口"""
cur_handle = self.driver.current_window_handle
handles = self.driver.window_handles
"""方法一:判断所有的窗口,如果窗口标题包含注册就跳转"""
for handle in handles:
if "注册" in handle.title():
self.driver.switch_to_window(handle)
"""方法二:直接跳转到最新的窗口,即最后一个窗口"""
# self.driver.switch_to_window(handles[-1])
"""输入用户名和和密码"""
self.driver.find_element_by_id('TANGRAM__PSP_4__userName').send_keys('username')
self.driver.find_element_by_id('TANGRAM__PSP_4__userNameTip').send_keys('password')
sleep(2)
"""跳转到百度首页,输入账号密码"""
self.driver.switch_to_window(cur_handle)
self.driver.find_element_by_id("TANGRAM__PSP_11__footerULoginBtn").click() # 点击用户名登录
self.driver.find_element_by_id('TANGRAM__PSP_11__userName').send_keys('username')
self.driver.find_element_by_id('TANGRAM__PSP_11__password').send_keys('password')
sleep(2)
Frame 介绍
- 在web自动化中,如果一个元素定位不到,那么很大可能是在iframe中。
- 什么是frame?
- frame是html中的框架,在html中,所谓的框架就是可以在同一个浏览器中显示不止一个页面。
- 基于html的框架,又分为垂直框架和水平框架(cols,rows)
- Frame分类
- frame标签包含frameset、frame、iframe三种
- frameset和普通的标签一样,不会影响正常的定位,可以使用index、id、name、webelement任意种方式定位frame。
- 而frame与iframe对selenium定位而言是一样的。selenium有一组方法对frame进行操作
- 演示: https://www.w3school.com.cn/tiy/t.asp?f=html_frame_cols
- 在演示地址中输入以下代码,点击“运行代码”
<html>
<frameset rows="25%,50%,25%">
<frame src="/example/html/frame_a.html">
<frame src="/example/html/frame_b.html">
<frame src="/example/html/frame_c.html">
</frameset>
</html>

image.png
多Frame 切换
- frame存在两种:
- 一种是嵌套的,一种是未嵌套的
- 切换frame
-
driver.switch_to.frame()#根据元素id或者index切换frame -
driver.switch_to.default_content()#切换到默认frame -
driver.switch_to.parent_frame()#切换到父级frame
-
- 处理未嵌套的iframe
driver.switch_to_frame("frame的id")-
driver.switch_to_frame("frame_index")frame无ID的时候依据索引来处理,索引从0开始driver.switch_to_frame(0)
- 处理嵌套的iframe
- 对于嵌套的先进入到iframe的父节点,再进到子节点,然后可以对
子节点里面的对象进行处理和操作 driver.switch_to.frame("父节点")driver.switch_to.frame("子节点")
- 对于嵌套的先进入到iframe的父节点,再进到子节点,然后可以对
多frame切换案例
- 打开包含frame的web页面 https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable
- 打印请拖拽我元素的文本
- 打印点击运行元素的文本
image.png - 分析:
-
请拖拽我元素在 iframe 中
image.png -
点击运行元素在外层的frame中
image.png - 进行编码:
-
请拖拽我元素在 iframe 中
from time import sleep
from lessons.selenium_test.base import Base
class TestFrame(Base):
def test_frame(self):
self.driver.get("https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable")
self.driver.switch_to.frame('iframeResult') # 切换到iframe中
drag = self.driver.find_element_by_id("draggable") # 获取drag元素
print(drag.text) # 打印元素的文本信息
"""切换到默认的frame
方法一:切换到父节点
方法二:切换到默认frame
"""
self.driver.switch_to.parent_frame() # 切换到父节点
self.driver.switch_to.default_content() # 切换到默认frame
print(self.driver.find_element_by_id("submitBTN").text) # 打印点击运行元素的文本
sleep(3)
- 运行结果:
rootdir: D:\Programs\DevOps\Python_Practice\lessons\selenium_test
plugins: allure-pytest-2.8.40
collecting ... collected 1 item
test_frame.py::TestFrame::test_frame
============================= 1 passed in 14.95s ==============================
Process finished with exit code 0
PASSED [100%]请拖拽我!
点击运行
下一节:Selenium 多浏览器处理,包括Chrome、Firefox、Headless等的浏览器自动化支持。


