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

如何使用Selenium检测两个元素中任意一个是否可见?

使用Selenium检测两个元素任意一个可见性的解决方案

问题场景

页面包含搜索框与结果列表:

  • 搜索到内容时,显示结果列表
  • 未搜索到内容时,显示No Results Found提示

需要实现逻辑:

  1. 判断当前状态是「结果列表可见」还是「无结果提示可见」
  2. 无结果时,将搜索文本加入未找到列表;有结果时,点击对应结果

页面HTML结构(React渲染,结果列表会替换无结果提示的容器)

<div class="related-files-adder">
    <div class="MuiFormControl-root MuiTextField-root MuiFormControl-fullWidth">
        <div class="MuiInputBase-root MuiInput-root MuiInput-underline MuiInputBase-fullWidth MuiInput-fullWidth MuiInputBase-formControl MuiInput-formControl">
            <input placeholder="Search..." type="text" class="MuiInputBase-input MuiInput-input"> <!-- 搜索输入框 -->
        </div>
    </div>
    <div class="this is where the both no results and the table lives">
        <div> <!-- 该容器会被结果列表替换 -->
            <p class="lead">No Results Found</p>
        </div>
    </div>
</div>

已尝试方法的问题

  1. 错误使用EC.any_of
    直接调用EC.visibility_of_element_located作为判断条件,会始终返回true——因为该方法返回的是等待条件对象,而非布尔值,无法直接用于if判断:
if (EC.visibility_of_element_located((By.XPATH, restultsTablePath))):
    print("即使显示无结果,这里也会输出true")
if (EC.visibility_of_element_located((By.XPATH, noResultsPath))):
    print("即使显示结果列表,这里也会输出true")
  1. find_element().is_displayed()抛出异常
    当元素不存在时,find_element会直接抛出NoSuchElementException,导致代码崩溃:
if (driver.find_element(By.XPATH, restultsTablePath).is_displayed()):
    print("表格可见时正常,不可见时直接崩溃")
  1. 关于元素过时(staleness)的疑问
    React渲染会替换DOM元素,不确定应该监听哪个元素的过时状态。

解决方案

方案1:结合WebDriverWait与EC.any_of(推荐)

正确使用等待条件,等待两个元素中任意一个可见,同时处理React渲染的页面更新:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException

wait = WebDriverWait(driver, 10)

# 先获取结果容器的父元素,等待它过时(React重新渲染后该元素会被替换)
parent_container = driver.find_element(By.CSS_SELECTOR, "div.related-files-adder > div:nth-child(2)")
wait.until(EC.staleness_of(parent_container))

try:
    # 等待任意一个元素可见
    visible_element = wait.until(EC.any_of(
        EC.visibility_of_element_located((By.XPATH, restultsTablePath)),
        EC.visibility_of_element_located((By.XPATH, noResultsPath))
    ))
    
    # 判断当前是哪种状态
    if "No Results Found" in visible_element.text:
        # 无结果,将搜索文本加入列表
        not_found_list.append(search_text)
    else:
        # 有结果,点击对应元素(示例:点击第一行结果)
        visible_element.find_element(By.XPATH, "./tbody/tr[1]").click()
except TimeoutException:
    # 处理超时情况(如页面加载失败)
    print("页面超时,未找到目标元素")

方案2:使用find_elements避免异常

find_elements会返回匹配元素的列表(无匹配时返回空列表),不会抛出异常,可结合is_displayed()判断可见性:

# 检查结果列表是否存在且可见
results_tables = driver.find_elements(By.XPATH, restultsTablePath)
if results_tables and results_tables[0].is_displayed():
    # 有结果,执行点击操作
    results_tables[0].find_element(By.XPATH, "./tbody/tr[1]").click()
else:
    # 检查无结果提示是否存在且可见
    no_results = driver.find_elements(By.XPATH, noResultsPath)
    if no_results and no_results[0].is_displayed():
        # 无结果,加入列表
        not_found_list.append(search_text)

关于元素过时的处理

React会替换结果容器内的DOM元素,因此可以监听父容器(即包含结果列表/无结果提示的div)的过时状态,确保页面完成渲染后再进行判断,避免获取到旧的DOM元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:06:03