selenium多窗口、多iframe切换、alert、3种等待

1、多标签/多窗口之间的切换

场景:

在页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要切换到新打开的窗口上进行操作。这种情况下,需要识别多标签或窗口的情况。

操作方法:

switch_to.window()方法:切换窗口。可以实现在不同的窗口之间切换。current_window_handle:获得当前窗口句柄。

window_handles: 获取所有窗口句柄。

提示:句柄就可以理解成浏览器窗口的id值。

操作说明:

获取所有窗口的句柄
handles = driver.window_handlers
调用该方法会得到一个列表,在selenium运行过程中的每一个窗口,都有一个对应的值存放在里面。
(换句话说,有多少个窗口,就有多少个句柄)
通过窗口的句柄进入的窗口
driver.switch_to_window(handles[n]) 

练习

python 复制代码
"""
1.学习目标:
    必须掌握web中多窗口切换方法
2.语法(操作步骤)
    2.1 获取当前窗口句柄
        driver.current_window_handle
    2.2 点击页面中的超链接触发多窗口
    2.3 获取所有窗口句柄
        driver.window_handles
    2.4 进入新窗口
        switch_to.window(handles[1])
    2.5 操作新窗口中的元素
        按实际工作需求编写
    2.6 退出新窗口
        switch_to.window(handles[0])

3.需求
    在页面中,实现多窗口切换。
"""
# 1.导入selenium
from selenium import webdriver
import time
from selenium.webdriver.common.by import By

# 2.打开浏览器
driver = webdriver.Chrome()

#3.打开百度一下页面
driver.get("https://www.baidu.com/")
time.sleep(2)

## 4. 多窗口切换操作
# 4.1 获取当前窗口句柄
handle = driver.current_window_handle
print('点击之前的窗口句柄是:', handle)
print('点击前的url:', driver.current_url)

# 4.2 点击页面中的百度热搜 超链接触发多窗口
driver.find_element(By.XPATH,'//a[text()="新闻"]').click()
time.sleep(3)

# 4.2 获取所有窗口句柄
handles = driver.window_handles

# 4.3 进入新窗口
driver.switch_to.window(handles[-1])
print('点击之后浏览器所有的窗口句柄是:', handles)
print('点击后的url:', driver.current_url)

# 4.5 退出新窗口
# 你需要退到哪个窗口就写哪个窗口的handle索引
# 因为handle在上边赋值等于第一个窗口了,这里就可以写handle
# 也可以写handles[0]
driver.switch_to.window(handle)
time.sleep(10)

# 5.关闭浏览器
driver.quit()
"""
点击之前的窗口句柄是: 2CC28D229393F6E1A07AA345F0E2D98D
点击前的url: https://www.baidu.com/
点击之后浏览器所有的窗口句柄是: ['2CC28D229393F6E1A07AA345F0E2D98D', '6A8E0C9DD6E357F82727264A8A28C281']
点击后的url: https://news.baidu.com/
"""

2、iframe切换

场景

页面会进行一层一层的嵌套,只有切换到嵌套的iframe页面,才可以定位到iframe页面里的标签属性

python 复制代码
# 1、通过name属性进行定位,前提是iframe有name属性
driver.switch_to.frame("login_frame")
 
# 2、通过iframe索引去切换,注意iframe层级关系
driver.switch_to.frame(1)
 
# 3、通过元素去定位,先找到要定位的iframe元素,然后再作为参数传入
iframe = driver.find_element("xpath","//iframe[@id='login_frame']")
driver.switch_to.frame(iframe)
 
# 扩展:
# 关于进入iframe页面怎么退回到主页面
driver.switch_to.default_content()
# 关于进入iframe页面怎么退回到父级的iframe
driver.switch_to.parent_frame()

练习

访问QQ邮箱为例:使用账号密码登录

python 复制代码
"""
举例:已QQ邮箱为例
实现功能:使用账号密码登录QQ邮箱
步骤:定位到密码登录的iframe中(嵌套了2层),并在该iframe中找到"密码登录"元素并点击,然后到账号密码页面进行输入

"""

import time
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://mail.qq.com/")

#隐性等待
driver.implicitly_wait(10)

# 1、通过name属性进行定位,前提是iframe有name属性
# driver.switch_to.frame("login_frame")

# 2、通过iframe索引去切换,注意iframe层级关系
# driver.switch_to.frame(1)

# 3、通过元素去定位,先找到要定位的iframe元素,然后再作为参数传入【常用】
iframe = driver.find_element(By.XPATH, "//iframe[@class='QQMailSdkTool_login_loginBox_qq_iframe']")
driver.switch_to.frame(iframe)

iframe2 = driver.find_element(By.XPATH, "//iframe[@id='ptlogin_iframe']")
driver.switch_to.frame(iframe2)
# 点击账号密码登录
driver.find_element(By.XPATH, "//a[text()='密码登录']").click()

# 输入账号
driver.find_element(By.ID, "u").send_keys("username")

# 输入密码
driver.find_element(By.ID, "p").send_keys("password")

# 点击登录
driver.find_element(By.XPATH, "//input[@id='login_button']").click()

# 强制等待5s
time.sleep(5)

# 退出浏览器
driver.quit()

3、切换alert

accept():确定

dismiss():取消

send_keys():输入

python 复制代码
import time
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

"""
1、某一操作导致alert(或prompt、confirm)弹窗出现
2、切换到弹窗中,driver.switch_to.alert 返回的是一个类的实例化对象,例如用alert接收它
"""
driver = webdriver.Chrome()
driver.get("https://www.w3school.com.cn/tiy/t.asp?f=eg_js_alert")
iframe = driver.find_element(By.XPATH,'//iframe[@id="iframeResult"]')
driver.switch_to.frame(iframe)
time.sleep(5)
# 触发弹窗的操作
driver.find_element(By.XPATH, '//button[text()="试一试"]').click()
time.sleep(1)
# 切换到alert
alert = driver.switch_to.alert
# 关闭弹窗
alert.accept()
time.sleep(7)
driver.quit()

4、XPATH轴定位

ancestor: 祖先

parent: 父节点

following-sibling -同级的弟弟元素

preceding-sibling - 同级的哥哥元素

关系:要找的元素是已知元素的XXX关系

用法: //...已知元素/轴定位名称::标签名[@xx=xx]

①定位到课程人数

//p[text()='课程人数']/preceding-sibling::p


//span[text()="柠檬班导师ice"]/ancestor::tr//span[text()="私信"]

或者

//span[text0="柠檬班导师ice"]/ancestor:td/following-sibling:td//span[text0="私信"

5、三种等待方式

①强制等待

强制等待是使线程休眠一定时间。强制等待一般在隐式等待和显式等待都不起作用时使用。示例代码如下:

python 复制代码
time.sleep(3)

②隐式等待

隐式等待的作用是全局的,是作用于整个 session 的生命周期,也就是说只要设置一次隐式等待,后面就不需要设置。如果再次设置隐式等待,那么后一次的会覆盖前一次的效果。

当在 DOM 结构中查找元素,且元素处于不能立即交互的状态时,将会触发隐式等待。

python 复制代码
driver.implicitly_wait(30)

③显式等待

显式等待是在代码中定义等待条件,触发该条件后再执行后续代码,就能够根据判断条件进行等待。程序每隔一段时间进行条件判断,如果条件成立,则执行下一步,否则继续等待,直到超过设置的最长时间。核心用法如下:

python 复制代码
# 导入显示等待
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
...
# 设置10秒的最大等待时间,等待 (By.TAG_NAME, "title") 这个元素点击
WebDriverWait(driver, 10).until(
    expected_conditions.element_to_be_clickable((By.TAG_NAME, "title"))
)
...

一个案例

python 复制代码
#导入依赖
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

class TestHogwarts():
def setup(self):
        self.driver = webdriver.Chrome()
        self.driver.get('https://ceshiren.com/')
#加入隐式等待
        self.driver.implicitly_wait(5)

def teardown(self):
#强制等待
        time.sleep(10)
        self.driver.quit()

def test_hogwarts(self):
#元素定位,这里的category_name是一个元组。
        category_name = (By.LINK_TEXT, "开源项目")
# 加入显式等待
        WebDriverWait(self.driver, 10).until(
            expected_conditions.element_to_be_clickable(category_name))
# 点击开源项目
        self.driver.find_element(*category_name).click()
相关推荐
安冬的码畜日常4 小时前
【玩转 Postman 接口测试与开发2_006】第六章:Postman 测试脚本的创建(中):脚本的位置与执行顺序、AI助手及私有模块的使用
测试工具·postman·测试脚本·postbot·package library
上海_彭彭6 小时前
【提效工具开发】Python功能模块执行和 SQL 执行 需求整理
开发语言·python·sql·测试工具·element
测试19988 小时前
2024软件测试面试热点问题
自动化测试·软件测试·python·测试工具·面试·职场和发展·压力测试
代码欢乐豆9 小时前
数据采集之selenium模拟登录
python·selenium·测试工具
测试杂货铺12 小时前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
小码哥说测试13 小时前
接口测试用例设计的关键步骤与技巧解析!
自动化测试·测试工具·jmeter·职场和发展·测试用例·接口测试·postman
小白学大数据20 小时前
正则表达式在Kotlin中的应用:提取图片链接
开发语言·python·selenium·正则表达式·kotlin
awonw1 天前
[java][框架]springMVC(1/2)
测试工具·postman
迃幵chen1 天前
wireshark-网络分析工具
网络·测试工具·wireshark
孤蓬&听雨1 天前
RabbitMQ自动发送消息工具(自动化测试RabbitMQ)
分布式·测试工具·自动化·rabbitmq·自动发送消息