📅  最后修改于: 2023-12-03 15:34:04.287000             🧑  作者: Mango
在使用 Selenium 进行自动化测试时,我们需要等待页面元素加载完成后再执行操作,否则可能会导致找不到元素而抛出异常。为了避免这种情况的发生,我们可以使用等待机制来控制测试脚本的执行时间。在 Selenium 中,等待机制有两种:隐式等待和显式等待。
本文将着重介绍 Python Selenium 中的显式等待机制,并给出一些使用实例。
显式等待是一种按条件等待页面元素加载完成的机制。我们可以指定等待的最长时间,并指定一个条件,当条件满足时,程序继续执行。
使用显式等待的好处在于,如果在指定的时间内条件还未满足,则会抛出 TimeoutException
异常,而不是找不到元素引发的异常。这样可以更好地控制程序的执行时间。
Python Selenium 中的显式等待需要通过 WebDriverWait
类来实现,具体使用方法如下:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 创建一个 WebDriver 对象
driver = webdriver.Chrome()
# 打开网页
driver.get("https://www.example.com")
# 创建一个 WebDriverWait 对象,并指定等待最长时间为 10 秒
wait = WebDriverWait(driver, 10)
# 等待元素加载完成,并返回该元素
element = wait.until(EC.presence_of_element_located((By.ID, "my-id")))
上面的代码中,我们通过 presence_of_element_located
条件指定等待直到 ID
属性为 "my-id"
的元素出现。WebDriverWait
类会一直等待,直到该元素加载完成,或者等待最长时间结束。
如果在最长等待时间内元素还没有加载完成,则会抛出 TimeoutException
异常。
Python Selenium 中常用的条件类别如下:
presence_of_element_located(locator)
: 元素存在于 DOM 中(不一定可见)。visibility_of_element_located(locator)
: 元素存在于页面 DOM 中,并且可见。element_to_be_clickable(locator)
: 元素存在,并且可被点击。title_contains(title)
: 页面标题包含指定文本。title_is(title)
: 页面标题等于指定文本。text_to_be_present_in_element(locator, text)
: 元素文本包含指定文本。text_to_be_present_in_element_value(locator, text)
: 元素的 value 属性包含指定文本。alert_is_present()
: 页面中存在 alert 弹窗。示例如下:
# 等待元素可见
wait.until(EC.visibility_of_element_located((By.ID, "my-id")))
# 等待元素可被点击
wait.until(EC.element_to_be_clickable((By.ID, "my-id")))
# 等待页面标题包含指定文本
wait.until(EC.title_contains("指定文本"))
# 等待元素文本包含指定文本
wait.until(EC.text_to_be_present_in_element((By.ID, "my-id"), "指定文本"))
# 等待 alert 弹窗
wait.until(EC.alert_is_present())
在有些情况下,元素的属性可能不是唯一的,我们无法准确地匹配元素。这时,我们可以使用模糊匹配的方式,通过 By
类中的模糊匹配方式来指定元素。
例如,假设我们要查找 class
属性包含 "my-class"
的元素,但是页面上可能还有其他元素包含 "my-class"
的子串,那么我们可以使用如下方式:
from selenium.webdriver.common.by import By
# 查找 class 属性包含 "my-class" 的元素
element = driver.find_elements(By.CSS_SELECTOR, "[class*=my-class]")
上述代码中,我们使用 CSS_SELECTOR
方式匹配元素,其中 "*="
表示包含子串。这样我们就能匹配到 class
属性包含 "my-class"
的所有元素。
下面我们给出一个完整的示例,演示如何使用 Python Selenium 进行显式等待。
在这个示例中,我们打开 Python 官网,然后在搜索框中输入 "selenium"
,等待搜索结果页面加载完成,并在控制台中输出第一条搜索结果的链接。
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 对象
driver = webdriver.Chrome()
# 打开 Python 官网
driver.get("https://www.python.org/")
# 查找搜索框并输入关键词
search_box = driver.find_element(By.ID, "id-search-field")
search_box.send_keys("selenium")
# 等待搜索结果页面加载完成
wait = WebDriverWait(driver, 10)
search_button = driver.find_element(By.ID, "submit")
search_button.click()
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".list-recent-events")))
# 查找并输出第一条搜索结果链接
result = driver.find_element(By.CSS_SELECTOR, ".list-recent-events li:first-child a")
print(result.get_attribute("href"))
# 关闭 WebDriver 对象
driver.quit()
运行上述代码,输出结果如下:
https://www.python.org/dev/peps/pep-0417/
Python Selenium 中的显式等待机制可以让我们更好地控制程序的执行时间,并减少因为元素加载过慢而引发的异常。我们可以根据不同的需求,使用不同的条件进行等待,使得测试脚本更加准确和稳健。