
本文介绍如何使用 css 选择器的 `:not()` 伪类,在 selenium(v4.17.2+)中高效筛选出未被 `style=”display: none;”` 隐藏的 `
` 行元素,避免遍历无效节点导致的性能下降。
在 Web 自动化数据采集场景中,常遇到表格(
)内部分
行通过内联样式 style=”display: none;” 动态隐藏。若直接用 By.CLASS_NAME 或 By.TAG_NAME 获取所有行再逐个判断 is_displayed(),不仅逻辑冗余,还会因大量无效元素触发冗余 DOM 查询和渲染状态检查,显著拖慢执行速度——尤其在含数百行的动态表格中尤为明显。
推荐采用 CSS 选择器原生过滤 方案,利用 浏览器 引擎的高效匹配能力,在查找阶段即排除隐藏节点。针对问题中的 HTML 结构:
可使用如下精确选择器:
from selenium.webdriver import By results = driver.find_elements(By.CSS_SELECTOR, "tr.items:not([style='display: none;'])" )
✅ 优势说明:
- tr.items 精准匹配带 class=”items” 的行;
- :not([style=’display: none;’]) 排除 style 属性值 严格等于 “display: none;” 的元素(注意:不匹配 style=”display: none; margin: 0;” 等复合值);
- 全程由浏览器原生 CSS 引擎执行,零 Python 层循环,性能最优。
⚠️ 注意事项:
-
若目标元素的 style 属性可能包含其他样式(如 style=”display: none; opacity: 0;”),上述写法将失效。此时需改用 XPath 或 JavaScript 执行更灵活的判断:
results = driver.find_elements(By.XPATH, "//tr[@class='items'and not(contains(@style,'display: none'))]" )
-
is_displayed() 方法虽语义清晰,但 不应在 find_elements 后补过滤(如 [el for el in els if el.is_displayed()]),因其会强制触发每元素的布局计算,严重降低效率;
-
确保页面已完全加载且目标元素已渲染完成,必要时配合显式等待:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC wait = WebDriverWait(driver, 10) visible_rows = wait.until(EC.presence_of_all_elements_located( (By.CSS_SELECTOR, "tr.items:not([style='display: none;'])") ) )
综上,善用现代 CSS 选择器的 :not()、属性匹配等能力,是提升 Selenium 数据提取效率的关键实践。在兼容 Selenium 4+ 的项目中,应优先选择声明式选择器而非运行时过滤。