WEB自动化_强制等待与智能等待(显示等待、隐式等待)
1、应用场景:
大多数web应用程序都是使用Ajax和JavaScript开发的。当前浏览器加载页面时,我们想要与之交互的元素可能尚未被加载出来。
此刻,不仅难以识别元素,而且很容易定位不到元素,抛出异常。
使用等待可以解决这个问题。
2、强制等待:
time.sleep(5)
强制等待5秒,如果在第3秒找到了元素,还会继续等第4第5秒。
3、智能等待->隐式等待:
driver.implicitly_wait(3) # 隐式等待
.
设置一个超时时间。
在这个时间内,不断寻找元素,超时找不到就报错timeout,超时前找到,就继续执行,而不会接着等待。
比如超时等待时间是5s,第3秒找到了,就会继续执行,而不等第4第5秒。
优点:
1、使用简单,一般在创建 driver 之后设置一个隐式等待,设置后的元素定位全部都会进入隐式等待的逻辑(一次设置,终生有效)。
缺点:
1、无法为指定元素设置等待,需要页面完全加载,相对浪费时间,降低脚本执行速度。每一次元素定位,都会进入隐式等待的逻辑,会降低脚本执行速度。
"""
from selenium import webdriver # 申明
# 创建浏览器驱动对象
driver = webdriver.Chrome("D:\\chromedriver-V88.exe")
# 智能等待_隐性等待
driver.implicitly_wait(3)
# 访问网址
driver.get("http://127.0.0.1:8088/")
"""
4、智能等待->显示等待:
设置一个超时时间和一个元素查找条件,间隔时间默认0.5秒。
在这个时间内,不断寻找元素,超时找不到就报错timeout,超时前找到,就继续执行,而不会接着等待。
比如超时等待时间是5s,第3秒找到了,就会继续执行,而不等第4第5秒。
优点:
1、不需要等页面完全加载,想对节省时间。
2、可以指定需要等待的元素,对一些加载缓慢的元素,可以为其增加等待时间。
缺点:
1、使用相对复杂,代码量多,只对申明了显示等待的元素有效,每次等待都需要再写一遍代码。
4.1、智能等待_显示等待_案例
# 申明
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 智能等待_显示等待
# 每隔0.5秒检查一次,最多等待10秒
WebDriverWait(driver, 10, 0.5).until(
# 设置等待条件,EC:负责等待条件
# invisibility_of_element_located:元素被加载出来并且在页面上可见
EC.invisibility_of_element_located(
(By.CSS_SELECTOR, # 由By告诉元素定位表达式
# 等待项目管理页面出现
"body > section > div.left-side.sticky-left-side > div.left-side-inner > ul > li:nth-child(2) > a > span")
)
)
使用时只需要修改 "By.ID,'1'" 参数即可。
WebDriverWait(driver,60,0.5).until(EC.presence_of_element_located((By.ID,'1')))
5、总结:
1、如果对代码执行速度要求高,尽量避免使用隐式等待,在需要等待的地方都用显示等待。
例如:某元素定位之前发生了页面元素刷新。
2、如果对代码执行速度要求低,可以显隐结合使用:
2.1、申明一个隐式等待,全局通用。
2.2、对一些加载特别缓慢的元素,设置显示等待,适当为其增加等待时间。
2.3、当显示等待与隐式等待同时出现的时候,取时间较多的一个。
6、封装显示等待
# 封装显示等待
def webElementWait(driver, timeout, lo_time, by_locate, locate):
"""
封装显示等待,返回元素对象
:param driver: 浏览器驱动
:param timeout: 最大等待时间
:param lo_time: 轮询时间
:param by_locate: 元素定位方式
:param locate: 元素定位表达式
:return: 元素对象
"""
return WebDriverWait(driver, timeout, lo_time).until(
# 设置等待条件
EC.invisibility_of_element_located(
(by_locate, locate)
))
# 调用'显示等待'函数
ele = webElementWait(driver, 10, 0.5, By.XPATH, "/html/body/section/div[1]/div[3]/ul/li[1]/a/span")
print(ele.text)