【selenium】设置元素等待


一、前言

selenium中有三种时间等待:

  • 强制等待:sleep
  • 隐式等待:implicitly_wait
  • 显示等待:WebDriverWait

其中,这三种方法各有优缺点:
| 元素等待方式 | 优点 | 缺点|
|–|–|–|
| sleep | 使用起来最简单,可以选择在程序调试时使用 | 浪费很多的时间,影响效率 |
| implicitly_wait | 一旦设置,在WebDriver对象实例整个周期都起到作用 | 不够灵活 |
| WebDriverWait | 节省等待时间,执行效率高 | 使用起来,难度较上两个比较高 |

二、强制等待

让程序暂停运行一定的时间,等待时间达到要求的时间后继续运行。

使用前,需要先导入time模块:

import time

在前面的文章中,已经多次使用过,这里就不做演示了。

需要注意的是,对于定位不到元素的时候,从耗时方面来讲,隐式等待强制等待没什么区别。

三、隐式等待

implicitly_wait()默认参数的单位为秒,默认值为0。

如果在最大超时时间内找到元素了,会开始执行下一操作,未找到元素,则会抛出NoSuchElementException 异常。

以百度为例:

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

driver = webdriver.Chrome()
# 访问百度
driver.get('https://baidu.com')
start = time.time()
# 设置最大等待时间为3秒
driver.implicitly_wait(3)

try:
    # 使用id定位一个不存在的元素
    driver.find_element(By.ID, 'yyds')
except Exception as exception:
    # 打印异常
    print(exception)
    # 打印程序运行时间
    print(f'耗时:{time.time()-start}')
# 关闭所有页面
driver.quit()

四、显示等待

需要导入模块:

from selenium.webdriver.support.ui import WebDriverWait

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

  • driver: 传入WebDriver实例;
  • timeout:指最大超时时间,默认单位为秒;
  • poll_frequency:调用until或until_not方法,每隔一定时间不断尝试是否能找到页面元素,默认间隔是0.5s,可自行调整间隔时间。
  • ignored_exceptions:超时后的异常信息,默认情况下NoSuchElementException 异常。

WebDriverWait一般和until()until_not()配合使用:

  • until() 当某元素出现 或 某条件成立则继续执行
  • until_not 当某元素消失 或 某条件不成立则继续执

untiluntil_not中的method参数一定要是可以调用的对象,我们可以用selenium提供的expected_conditions,提供一些场景的判断。

但使用expected_conditions,需先导入:

from selenium.webdriver.support import expected_conditions as EC

常用的expected_conditions方法如下:

方法 说明
title_is 判断当前页面的 title 是否完全等于(==)预期字符串
title_contains 判断当前页面的 title 是否包含预期字符串
presence_of_element_located 判断某个元素是否被加到了 dom 树里,并不代表该元素一定可见
visibility_of_element_located 判断元素是否可见(可见代表元素非隐藏,并且元素宽和高都不等于 0)
visibility_of 作用和上一个方法类似,但传入参数是定位的元素,即element
presence_of_all_elements_located 判断是否至少有 1 个元素存在于 dom 树中。举例:如果页面上有 n 个元素的 class 都是’qw’,那么只要有 1 个元素存在,这个方法就返回 True
text_to_be_present_in_element 判断某个元素中的 text 是否包含了预期的字符串
text_to_be_present_in_element_value 判断某个元素中的 value 属性是否包含了预期的字符串
frame_to_be_available_and_switch_to_it 判断该 frame 是否可以 switch进去,如果可以的话,返回 True 并且 switch 进去,否则返回 False
invisibility_of_element_located 判断某个元素中是否不存在于dom树或不可见
element_to_be_clickable 判断某个元素中是否可见并且可点击
staleness_of 等某个元素从 dom 树中移除,注意,这个方法也是返回 True或 False
element_to_be_selected 判断某个元素是否被选中了,一般用在下拉列表
element_selection_state_to_be 判断某个元素的选中状态是否符合预期
element_located_selection_state_to_be 跟上面的方法作用一样,只是上面的方法传入定位到的 element,而这个方法传入 locator
alert_is_present 判断页面上是否存在 alert

以百度为例:

  • 定位一个存在的元素:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
# 访问百度
driver.get('https://www.baidu.com')
# 设置显式等待,超时时长最大为5s,每隔1s查找元素一次
# 根据id定位到元素位置
element = WebDriverWait(driver, 5, 1).until(
    EC.presence_of_element_located(('id', 'kw')))
# 在定位到的地方,输入CSDN
element.send_keys('CSDN')

  • 定位一个不存在的元素
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

driver = webdriver.Chrome()
# 访问百度
driver.get('https://www.baidu.com')
# 设置显式等待,超时时长最大为5s,每隔1s查找元素一次
# 根据id定位到元素位置
element = WebDriverWait(driver, 5, 1).until(
    EC.presence_of_element_located((By.ID, 'csdn')), message='超时了哟。。。')

得到提示:

selenium.common.exceptions.TimeoutException: Message: 超时了哟。。。

五、参考文章

Selenium自动化测试-设置元素等待


Author: Polaris119
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Polaris119 !
评论
  TOC