三种等待方式的区别
强制等待:
- 用以设置固定的线程休眠时间(s),使得整个脚本暂停。但是这种方式会导致这个脚本运行时间过长,一般情况下会在调试代码的时候使用,临时性添加
隐式等待:
- 隐式等待是全局的是针对所有元素,设置等待时间如10秒,如果10秒内出现,则继续向下,否则抛异常。可以理解为在10秒以内,不停刷新看元素是否加载出来。隐式等待只需要声明一次,一般在打开浏览器后进行声明。声明之后对整个drvier的生命周期都有效,后面不用重复声明。
- 使用场景:在时间范围内轮询查找元素,适用于解决找不到元素的问题。
- 弊端:无法解决交互问题,也无法自定义等待条件
显示等待:
- 显示等待是单独针对某个元素,设置一个等待时间如5秒,每隔0.5秒检查一次是否出现,如果在5秒之前任何时候出现,则继续向下执行,超过5秒尚未出现则抛异常。显示等待与隐式等待相对,显示等待必须在每个需要等待的元素前面进行声明。
- 使用场景:设定特定的等待条件,轮询操作,用来解决特定条件下的等待问题,比如点击等交互性行为,同时支持自定义等待条件
from selenium.webdriver.support.wait import WebDriverWait
# expected_conditions模块可以对网页上元素是否存在,可点击等等进行判断。
# 一般用于断言或与WebDriverWait配合使用
from selenium.webdriver.support import expected_conditions as EC
# 显示等待,每0.5秒检查一下元素是否加载出来,最长等待时间5秒
# 等待过程中如果定位到元素,就直接执行后续的代码,反之等待5s后报错误信息
WebDriverWait(self.driver, 5, 0.5).until(
EC.presence_of_element_located((By.ID,"search-term"))).send_keys(keyword)
显示等待的高级应用:
1. 原理
2. 原理分析
import time
from selenium.webdriver.support.wait import WebDriverWait
driver = 'aaaa'
def fake_conditions(driver):
print("当前时间为",time.time())
WebDriverWait(driver,10,1).until(fake_conditions,"hogwarts")
-
until要传入的不是一个函数的调用,而是一个函数对象
-
源码中,method是通过参数传递过来的函数对象,在循环里去调用这个函数对象,默认给他传递了一个参数
3.expected_conditions使用原理
-
确定返回值是否为webelement对象,要进入condition的源码中进行查看
-
不是所有的expected_conditions的返回值都是webelement对象
4. 常见expected_conditions
针对元素,比如判断元素是否可点击,是否可见等 | element_to_be_clickable()、visibility_of_element_located() |
针对url | url.contains() |
针对标题 | title_is() |
针对frame | frame_to_be_available_ and_switch_to_it(locator) |
针对弹窗 | alert_is_present() |
5. 定制封装条件
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Chrome()
driver.get("https://vip.ceshiren.com/#/ui_study")
# 点击的目标按钮,期望出现元素
def muliti_click(target_element,next_element):
def _predicate(driver):
driver.find_element(*target_element).click()
return driver.find_element(*next_element)
# 结果为找到,return一个webelement对象
# 如果没有找到,会被until里的try捕获异常,报错,但是会一直循环,直到找到或者超时
return _predicate
# 封装需求,一直点击按钮,直到下一个页面出现为止
WebDriverWait(driver,5).until(
muliti_click(
# 这里需要两个括号,因为调用的函数内有解包操作
(By.ID,"primary_btn"),(By.XPATH,"//*[text()='该弹框点击两次后才会弹出']")
))
# driver.find_element(By.ID,"primary_btn").click()
time.sleep(3)
driver.close()
可根据until源码进行分析
推荐阅读文章链接:只需Docker,环境问题再也不是测开路上的『坑』_霍格沃兹测试开发学社的博客-CSDN博客 13