📜  python selenium 显式等待 - Python (1)

📅  最后修改于: 2023-12-03 15:34:04.287000             🧑  作者: Mango

Python Selenium 显式等待

在使用 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 中的显式等待机制可以让我们更好地控制程序的执行时间,并减少因为元素加载过慢而引发的异常。我们可以根据不同的需求,使用不同的条件进行等待,使得测试脚本更加准确和稳健。