一、元素等待的作用
受网络、PC配置、OS环境等影响,同一网页在不同条件下打开,完全加载出页面元素的时间不同。若元素未加载完成就立即定位元素,必然会定位失效,产生异常。传统上的sleep()函数所设置的等待时间是固定的某个值,若加载时间超过这个值,元素还没有加载出来就定位,则会产生异常;若加载时间小于这个值,虽然定位功能没有异常,但是会造成不必要的时间浪费而降低自动化执行效率。因此在实际自动化测试脚本中,引入“元素等待”的设置,适应不同加载时间下的元素定位,又能节省多余等待时间的浪费。
二、元素等待的类型&使用模块
1.相关模块
webdriver: 利用浏览器驱动打开本地主流浏览器
from selenium import webdriver
By: 用于元素定位
from selenium.webdriver.common.by import By
WebDriverWait:
显示等待
针对元素时必用到(严格区分大小写)
from selenium.webdriver.support.ui import WebDriverWait
expected conditions: 预期条件类(里面包含函数方法可以调用,用于
显示等待
)
from selenium.webdriver.support import expected conditions as EC
NoSuchElementException: 用于
隐式等待
抛出异常
from selenium.common.exceptions import NoSuchElementException
2.元素等待-显式等待
检测Baidu首页搜索按钮是否存在,若存在,则输入关键词“Selenium自学”,然后点击搜索按钮实现搜索。
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element_by_css_selector("#kw").send_keys("Selenium自学")
# 显示等待:判断搜索按钮是否存在;若存在,则点击该按钮
# 在当前页面,5s之内,每隔0.5s检测一次
element = WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located((By.ID,"su")))
element.click()
sleep(3)
driver.quit()
Tips:
判断搜索按钮是否存在时所用的EC.presence_of_element_located((By.ID,"su"))
,需要包含2层英文状态的圆括号,否则运行代码会出现异常。
具体原因可以参看此文:[Selenium]TypeError: _init_() takes 2 positional arguments but 3 were given_解决方案
3.元素等待-隐式等待
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from time import sleep,ctime
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.implicitly_wait(5) # 隐式等待时间=5s
# 检测搜索框是否存在
# 若超过5s后还没有定位到搜索框,则抛出NoSuchElementException的异常
# 若超过5s后还没有定位到搜索按钮,则抛出NoSuchElementException的异常
print(ctime()) # 打印开始时间
# 定位搜索输入框
driver.find_element_by_css_selector("#kw").send_keys("Python")
# 定位搜索按钮
driver.find_element_by_css_selector("#su").click()
except NoSuchElementException as msg:
print(msg)
finally:
print(ctime()) # 打印结束时间
sleep(3)