selenium 强制、隐式、显示等待(11种预置条件)

发布于:2024-10-09 ⋅ 阅读:(35) ⋅ 点赞:(0)

注:显示等待和隐式等待不可混用

强制等待

让当前正在执行的代码线程暂停运行。

示例:在电商网站的商品搜索页面,等待 5 秒之后,点击搜索按钮,如果页面加载速度很快,在 2 秒内生成,那么还需要等待 3 秒,直到累计等待 5 秒才会继续执行,但如果按钮生成时间超过 5 秒,代码继续执行时就可能找不到按钮,此时会抛出 NoSuchElementException 异常。

import time

try:
    # 打开商品搜索页面
    driver.get("https://www.example.com/search")

    # 强制等待5秒
    time.sleep(5)

    # 查找搜索按钮并点击
    driver.find_element(By.ID,'search_button_id').click()
except NoSuchElementException:
    print("按钮未找到,请检查页面元素或等待时间是否合适。")

隐式等待

在 driver 初始化时设置了等待时间(比如 5 秒),在整个 driver 的生命周期内,每次查找元素时,它都会在设定的时间内不断地检查页面,如果找到该元素,则代码继续执行,否则会抛出 NoSuchElementException 异常,表示没有在规定时间找到该元素。

示例:在电商网站的商品搜索页面,输入关键词并点击搜索按钮,如果在 5 秒内搜索框和搜索按钮成功加载并被找到,代码就会顺利执行。但如果超过 5 秒还没找到,就会抛出 NoSuchElementException 异常。

# 设置隐式等待5秒
driver.implicitly_wait(5)

try:
    # 打开商品搜索页面
    driver.get("https://www.example.com/search")

    # 查找搜索框并输入关键词
    driver.find_element(By.ID,'search_box_id').send_keys("手机")

    # 查找搜索按钮并点击
    driver.find_element(By.ID,'search_button_id').click()
except NoSuchElementException:
    print("页面元素未在规定时间内找到,请检查页面或等待时间设置。")

显示等待

在规定时间内不断地检查元素是否满足特定条件,一旦满足就立即执行后续操作,如果在规定时间没有满足特定条件,会抛出 TimeoutException 异常。

预置条件

等待元素可见

示例:设置最大等待时间为 10 秒,直到指定元素在页面上可见。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.element_to_be_clickable((By.ID,'element_id')))
等待元素不可见

例:设置最大等待时间为 10 秒,直到指定元素在页面上不可见。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.invisibility_of_element_located((By.ID,'element_id')))
等待元素可点击

例:设置最大等待时间为 10 秒,直到指定元素变为可点击状态。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.element_to_be_clickable((By.ID,'element_id')))
等待文本可见

例:设置最大等待时间为 10 秒,直到指定元素的文本可见。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.text_to_be_present_in_element((By.ID,'element_id'),'Expected_Text'))
等待文本在元素里可见

例:设置最大等待时间为 10 秒,直到指定文本在元素的值中可见。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.text_to_be_present_in_element_value((By.ID,'frame_id'),"Expected_Title"))
等待元素存在

例:设置最大等待时间为 10 秒,直到指定元素存在 DOM(文档对象模型) 中。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.presence_of_element_located((By.ID,'element_id')))
等待元素消失

例:设置最大等待时间为 10 秒,直到指定元素从 DOM(文档对象模型) 中移除。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.staleness_of(driver.find_element(By.ID,'element_id')))
URL 包含

例:设置最大等待时间为 10 秒,直到当前 URL 包含某个特定字符串。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.url_contains('expected_substring'))
标题包含

例:设置最大等待时间为 10 秒,直到当前页面标题包含某个字符串。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.title_contains('Expected Title')))
窗口可见

例:设置最大等待时间为 10 秒,直到新窗口出现并可见。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.new_window_is_opened(driver.window_handles))
等待切换iframe

例:设置最大等待时间为 10 秒,直到切换到某个 iframe 元素里。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

WebDriverWait(driver, timeout=10).until(EC.frame_to_be_available_and_switch_to_it((By.ID,'frame_id')))

高级

document.readyState 是表示当前网页状态的属性,共有三个状态:

  1. loading:文档正在加载,这个阶段 HTML 结构正在被解析,外部资源(如样式表、脚本、图片等)可能还在下载过程中。
  2. interactive:文档已经完成解析,DOM(文档对象模型)已经构建完成,但是像图片、样式表、脚本等外部资源可能还没有完全加载完成。此时用户已经可以与页面进行交互了,例如点击已经存在的 HTML 元素。
  3. complete:页面的所有资源(包括 HTML 结构、脚本、样式表、图片等)都已经加载完成,整个页面处于完全可用的状态。
设置检查条件的频率

示例:总超时时间为 10 秒,每 2 秒检查一次页面的 document.readyState 是否为 complete,直到页面加载完成。

from selenium.webdriver.support.wait import WebDriverWait

WebDriverWait(driver, timeout=10, poll_frequency=2).until(lambda d: d.execute_script("return document.readyState") == "complete")
自动忽略特定异常进行等待

示例:在等待特定元素时,如果出现 NoSuchElementException 异常,会自动忽略该异常继续等待,直到找到元素或者超时时间到达。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import NoSuchElementException

WebDriverWait(driver, timeout=10, ignored_exceptions=[NoSuchElementException]).until(lambda d: d.find_element(By.ID, "element_id"))
自定义超时提示信息

示例:在等待页面加载时,如果 10 秒内未加载完成,会捕获 TimeoutException 异常并打印自定义的超时消息。

from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException

try:
    WebDriverWait(driver, timeout=10.until(lambda d: d.execute_script("return document.readyState") == "complete")
except TimeoutException:
    print("页面加载超时,请检查网络连接。")