You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium WebDriverWait满足条件仍抛出TimeoutException

解决Selenium等待超时但仍能获取元素的异常问题

你的问题出在try-finally的执行逻辑上:finally块不管try里的代码是否抛出异常,都会强制执行。所以即使WebDriverWait超时抛出了TimeoutException,finally里的解析代码还是会运行——刚好此时目标元素已经加载完成,所以能输出结果,但超时异常依然会被抛出。

而且你明明已经用Selenium等待到了元素(如果等待成功的话),却还要用BeautifulSoup重新解析页面,完全没必要,反而多此一举。

修正后的最优写法

把业务逻辑放在try块内,等待成功后直接用Selenium操作元素,finally只负责关闭浏览器:

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

driver = webdriver.Edge(executable_path=r'path\to\MicrosoftWebDriver.exe')
driver.get('https://website')

try:
    # 等待所有目标元素出现,超时时间10秒
    elements = WebDriverWait(driver, 10).until(
        EC.presence_of_all_elements_located((By.CLASS_NAME, "class name"))
    )
    # 直接用Selenium获取元素属性,无需BeautifulSoup
    for element in elements:
        result = element.get_attribute('href')
        print(result)
finally:
    # finally仅做浏览器关闭的清理工作
    driver.quit()

为什么这样改

  • 业务逻辑移到try块后,只有当等待成功(元素确实加载完成)时才会执行获取属性的代码,不会出现「输出结果却抛异常」的矛盾情况。
  • 用presence_of_all_elements_located代替presence_of_element_located,一次性获取所有目标元素,贴合你原来用findAll的逻辑。
  • 直接使用Selenium的get_attribute方法获取href,省去BeautifulSoup解析页面的步骤,效率更高,也更符合Selenium的使用逻辑。

如果确实需要用BeautifulSoup

如果有复杂HTML解析需求,也应该在等待成功后再解析页面:

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

driver = webdriver.Edge(executable_path=r'path\to\MicrosoftWebDriver.exe')
driver.get('https://website')

try:
    # 等待目标元素出现
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CLASS_NAME, "class name"))
    )
    # 等待成功后再解析页面
    html_input = driver.page_source
    soup = BeautifulSoup(html_input, features="html.parser")
    for each_item in soup.findAll(class_='class name'):
        result = each_item['href']
        print(result)
finally:
    driver.quit()

核心问题就是你把业务逻辑放在了finally块,导致即使等待超时,代码依然会执行,同时超时异常被抛出。调整后让业务逻辑依赖等待成功的结果,就能彻底解决这个问题。

内容的提问来源于stack exchange,提问作者Jason Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 06:55:00