Python+Selenium4三大等待&预期条件_web自动化(4)

目录

0. 上节回顾

1. 定位失败的原因

2. 强制等待

3. 隐式等待

4. 显式等待 【重点难点】

4.1. 实例化 WebDriverWait 对象

4.2. 指定等待条件

4.3. 等待条件的具体要求

4.3. 1. 等待条件是一个函数

4.3. 2. 返回值是布尔值

4.3. 3. 只有一个参数,参数值是driver

4.3. 4. 出现异常

5. 流畅等待 (最底层,最强大,最难)

5. 1. 元素闪现太快 

5. 2. 出现特殊异常

6. 等待策略可以复用

7. Selenium官网中:等待的警告

0. 上节回顾

  • WebDriver的角度看,有8种元素定位策略
  • 从浏览器的角度来看,有2种元素选择器:
    • CSS选择器执行效率高
    • XPath选择器使用效率高
  • 底层通过JS实现,可以通过F12进行获取、调试

1. 定位失败的原因

元素交互过程中出错:
  1. 元素不存在
  2. 元素不可见
  3. 元素被遮挡
  4. 元素被禁用

如:元素被延迟渲染

with get_webdriver() as driver:
    driver.get("http://118.24.147.95:8086/delay.html")
    ele = driver.find_element(By.XPATH, '//*[@id="content"]/input')
    print(ele)
selenium.common.exceptions.NoSuchElementException: Message: no such element:
Unable to locate element: {"method":"xpath","selector":"//*[@id="content"]/input"}
DEBUG秘技:

控制台输入 debugger 让网页停下来 

#cdp:chrome devtools 协议
driver.execute_cdp_cmd("Debugger.enable", {}) # JS断点 selenium 4 新特性 (执行的慢的话有概率失败)
driver.execute_script("setTimeout('debugger',0.1*1000)") #JS断电 selenium 3
pdb.set_trace()#python 断点
解决了定位失败的问题
with get_webdriver() as driver:
    driver.get("http://118.24.147.95:8086/delay.html")
    # cdp:chrome devtools 协议
    driver.execute_cdp_cmd("Debugger.enable", {})  # JS断点 selenium 4 新特性 (执行的慢的话有概率失败)
    driver.execute_script("setTimeout('debugger',0.1*1000)")  # JS断电 selenium 3
    pdb.set_trace()  # python 断点
    ele = driver.find_element(By.XPATH, '//*[@id="content"]/input')
    print(ele)
> f:\pythonworkspace\ui_p39_selenium4\1.py(18)<module>()
-> ele = driver.find_element(By.XPATH, '//*[@id="content"]/input')
(Pdb) 
通过 DEBUG ,发现很多的元素是通过 JS 动态创建、改变、修改的,如果要定位准许,需要 等待 ”JS 完成
相关的操作:
  • 强制等待 sleep
  • 隐式等待 implicitly_wait
  • 显式等待 WebDriverWait
  • 流畅等待 FluentWait

2. 强制等待

sleep 实际上编程语言中的语句:当程序执行到 sleep 指令时,会暂停 x 秒,然后再继续执行
import time
time.sleep(6) # 定位代码,延迟6秒再执行
  • 以秒为单位
  • 可以是浮点数:(0.1秒)
使用方法简单粗暴,但是相对呆板,应用场景不多
如:验证 【登录成功】
with get_webdriver() as driver:
    driver.get("http://101.34.221.219:8010/?s=user/loginInfo.html")
    driver.find_element(By.XPATH, "/html/body/div[4]/div/div[2]/div[2]/div/div/div[1]/form/div[1]/input", ).send_keys(
        "tiancao")
    driver.find_element(By.XPATH,
                        "/html/body/div[4]/div/div[2]/div[2]/div/div/div[1]/form/div[2]/div/input", ).send_keys(
        "ganju123")
    driver.find_element(By.XPATH,
                        "/html/body/div[4]/div/div[2]/div[2]/div/div/div[1]/form/div[3]/button", ).click()  # 点击登录
    time.sleep(1)  # sleep的值不好取,太大 或者 太小,都会失败
    msg = driver.find_element(By.XPATH, "//p[@class='prompt-msg']", ).text
    assert msg == "登录成功"  # 没有任何输出,说明断言成功
对于出现之后会 消失 的元素来讲,要求 sleep 的秒数相当精确
学习 selenium 中提供 等待 来进行解决

3. 隐式等待

原理:让 selenium 在查找元素时,如果失败,就重试
默认:参数为 0 表示禁用
启用:参数大于 1 即可
特点:一旦启用,全局 (driver) 生效
弊端:
  • 只会等待元素出现
  • 不会等待元素就绪
with get_webdriver() as driver:
    # driver.implicitly_wait(0) #禁用
    driver.implicitly_wait(10)  # 启用隐式等待,每一次等待最长不超过10秒
    driver.get("http://118.24.147.95:8086/delay.html")
    msg = driver.find_element(By.XPATH, '//*[@id="content"]/p').text
    ele = driver.find_element(By.XPATH, '//*[@id="content"]/input')
    assert msg == "大家好,我是北凡"
对于复杂的业务场景,不只要求元素存在,还要求元素的状态就绪
http://118.24.147.95:8086/flash.html
如果要对等待条件,进行定制,就需要用到显式等待

4. 显式等待 【重点难点

显示等待指的是 WebDriverWait 对象
所谓 显式 ,是为了相对于前面的 隐式 而言的,
在显式等待中:等待的时机、内容,根据清晰、直观、可控

4.1. 实例化 WebDriverWait 对象

  • 两个参数 (固定写法) driver: WebDriver实例 (浏览器对象)
  • 10 :超时时间,等待最多不超过10
WebDriverWait(driver, 10)

4.2. 指定等待条件

灵活写法(难写法)
msg = WebDriverWait(driver, 10).until(
lambda x: driver.find_element(
By.XPATH,
"//p[@class='prompt-msg']",
).text
)
# 等待条件(匿名函数)
lambda x: driver.find_element(
By.XPATH,
"//p[@class='prompt-msg']",
).text
x 是匿名函数的参数,被传递了 driver
driver = webdriver.Chrome()  # 启动浏览器 是空白页

driver.get("http://101.34.221.219:8010/?s=user/loginInfo.html")
driver.find_element(By.XPATH,"/html/body/div[4]/div/div[2]/div[2]/div/div/div[1]/form/div[1]/input",).send_keys("tiancao")
driver.find_element(By.XPATH,"/html/body/div[4]/div/div[2]/div[2]/div/div/div[1]/form/div[2]/div/input",).send_keys("ganju123")
driver.find_element(By.XPATH,"/html/body/div[4]/div/div[2]/div[2]/div/div/div[1]/form/div[3]/button",).click() # 点击登录

msg = WebDriverWait(driver, 10).until(lambda x: driver.find_element(
By.XPATH,
"//p[@class='prompt-msg']",
).text)
assert msg == "登录成功",f"{msg}" # 没有任何输出,说明断言成功
#driver.quit()

4.3. 等待条件的具体要求

成功例子:在等待中,定位元素,函数返回了布尔值True 再交互 

with get_webdriver() as driver:
    driver.get("http://118.24.147.95:8086/delay.html")
    ele = WebDriverWait(driver, 10).until(
        lambda x: driver.find_element(By.XPATH, '//*[@id="content"]/input')
    )
    ele.click()  # 元素交互
driver.find_element(By.XPATH, '//*[@id="content"]/input') 的返回值, 是一个对象,它布尔值是 True
失败的例子:在等待中,交互元素
   WebDriverWait(driver, 10).until(  # 定位元素
        lambda x: driver.find_element(By.XPATH, '//*[@id ="content"] /input').click()
    )
返回值是 driver.find_element(By.XPATH, '//* [@id="content"]/input').click() 是None,它的布尔值是 False

4.3. 1. 等待条件是一个函数

可以是普通函数
也可以是匿名函数
匿名函数 和普通函数有什么区别?
区别
普通函数
匿名函数
关键
def
lambda
名字
有名字
没有名字
长度
可以多行
只能一行
返回值
可选,用 return 指定
必选,返回表达式结果

4.3. 2. 返回值是布尔值

  • 必须是布尔值,不是布尔值, 也会按照布尔值进行判断
  • 如果判断为Ture,表示等待成功,停止等待
  • 如判断为False,表示等待失败,继续等到,直到超时,

4.3. 3. 只有一个参数,参数值是driver

4.3. 4. 出现异常

出现 NoSuchElementException 异常表示等待失败,将继续等待
出现其他异常,表示出错,停止等待
出现 TimeOut 异常,表示超时,停止等待
总结
1. 是个函数
2. 有且只有一个参数,参数值是 driver
3. 返回值应该是布尔值 如果是 Ture ,表示等待成功,停止等待
  • 如果是False,表示等待失败,继续等待,直到超时
  • 如果是 NoSuchElementException 异常,表示等待失败,继续等待
  • 如果是其他异常,表示出错,停止等待

如果,想要以False表示成功怎么办?可以使用 until_not 方法:

  • 如果是Ture,表示等待失败,继续等待,直到超时
  • 如果是False,表示等待成功,停止等待
# WebDriverWait(driver, 10).until(lambda x: False) # 会超时
WebDriverWait(driver, 10).until_not(lambda x: False) # 会成功

5. 流畅等待 (最底层,最强大,最难)

selenium 核心是用什么语言开发的? java
Java 语言中,流畅等待指的是 FluentWait 对象,是 WebDriverWait 的父类
Python 中,没有定义 FluentWait 对象,直接使用 WebDriverWait 对象完成流畅等待
和显式等待相比,流畅等待增加 2 个参数
  • 重试频率 (等待的原理:失败重试,多久重试一次?)
  • 忽略的异常列表
可以实现更加复杂的业务场景

5. 1. 元素闪现太快 

with get_webdriver() as driver:
    driver.get("http://118.24.147.95:8086/flash_fast.html")
    WebDriverWait(driver, 10, 0.01).until(  # 调整了重试频率
        lambda x: driver.find_element(By.XPATH, "//p")
    )

5. 2. 出现特殊异常

with get_webdriver() as driver:
    driver.get("http://118.24.147.95:8086/delay_alert.html")
    alert = WebDriverWait(
    driver,
    10,
    ignored_exceptions=[
    NoAlertPresentException
    ], # 在等待过程中,如果出现NoAlertPresentException, 就继续等待
    ).until(lambda x: driver.switch_to.alert)
    print(alert.text)

6. 等待策略可以复用

复用前
with get_webdriver() as driver:
    driver.implicitly_wait(10)  # 隐式等待只要设置一次
    driver.get("http://118.24.147.95:8086/flash.html")

    p = WebDriverWait(driver, 10).until(  # 显式等待要设置1次
        lambda x: driver.find_element(By.XPATH, "//p"))

    p = WebDriverWait(driver, 10).until(  # 显式等待要设置1次
        lambda x: driver.find_element(By.XPATH, "//input"))
复用后
with get_webdriver() as driver:
    driver.wait = WebDriverWait(driver, 10)  # 等待策略 设置1次
    driver.get("http://118.24.147.95:8086/flash.html")
    p = driver.wait.until(lambda x: driver.find_element(By.XPATH, "//p"))
    i = driver.wait.until(lambda x: driver.find_element(By.XPATH, "//input"))  # 到处使用

7. Selenium官网中:等待的警告

隐式等待 和显式 等待不要混用
在框架,只用显式等待(或者流畅等待)
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: Python Selenium 显示等待是一种在自动化测试中使用的技术,它可以让程序等待某个条件成立后再执行下一步操作。这种技术可以帮助我们避免在程序执行过程中出现不必要的等待时间,从而提高测试效率。在 Python Selenium 中,我们可以使用 WebDriverWait 类来实现显示等待。该类提供了一些方法,如 until() 和 until_not(),可以让我们等待某个条件成立或不成立后再执行下一步操作。 ### 回答2: PythonSelenium库是一个非常强大的工具,它可用于模拟用户操作浏览器,用于自动化测试和爬虫。在使用Selenium时,我们希望运行代码时能够等待几秒钟,直到某个条件满足后再继续执行后面的代码,这就是所谓的显示等待。 在Python中,可以通过使用WebDriverWait和expected_conditions来实现显示等待WebDriverWaitSelenium提供的用于等待的类,而expected_conditions是用于指定等待条件的模块。 首先,我们需要导入所需的库: ```python from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC ``` 然后,我们可以创建一个WebDriver实例(例如,使用ChromeDriver): ```python driver = webdriver.Chrome() ``` 接下来,我们可以使用WebDriverWait等待直到特定元素加载完毕: ```python wait = WebDriverWait(driver, 10) element = wait.until(EC.presence_of_element_located((By.ID, 'element-id'))) ``` 在这个例子中,我们指定了最长等待时间为10秒,然后使用presence_of_element_located函数指定了等待元素的条件(使用元素的ID来定位)。直到元素加载完毕后,WebDriverWait会继续执行下面的代码。 你也可以使用其他条件等待,例如使用visibility_of_element_located函数来等待元素可见,或者使用element_to_be_clickable函数来等待元素可点击等等。 总结起来,PythonSelenium库提供了WebDriverWait和expected_conditions来实现显示等待。通过等待指定的条件满足后再继续执行后面的代码,我们可以更灵活地处理各种等待情况,提高代码的健壮性和可靠性。 ### 回答3: python selenium中的显示等待是一种用于控制浏览器等待时间的技术。当使用selenium进行网页自动化测试时,有时我们需要等待某种条件的出现或消失,例如等待页面加载完全、元素可见、元素可点击等等,这时就可以使用显示等待来实现。 在python selenium中,可以通过使用WebDriverWait类来实现显示等待。该类需要传入driver实例和最大等待时间作为参数,并提供了一系列的until()和until_not()方法来指定等待条件。具体步骤如下: 1. 导入WebDriverWait和expected_conditions类: ``` from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC ``` 2. 创建WebDriverWait对象,并指定driver实例和最大等待时间: ``` wait = WebDriverWait(driver, 10) ``` 3. 使用until()方法指定等待条件,例如等待元素可见: ``` element = wait.until(EC.visibility_of_element_located((By.XPATH, "//*[@id='element-id']"))) ``` 4. 可以根据具体需要选择不同的等待条件,例如等待元素可点击: ``` element = wait.until(EC.element_to_be_clickable((By.XPATH, "//*[@id='element-id']"))) ``` 通过使用显示等待,我们可以避免写死固定的等待时间,提高测试的稳定性和效率。但需要注意设置合适的等待时间和等待条件,避免等待时间过长或条件设置不准确导致测试失败。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

天草柑橘

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

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

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

打赏作者

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

抵扣说明:

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

余额充值