最稳的方法是用 get_attribute() 和 is_displayed() 组合判断元素状态,因为 text 或 innerhtml 无法准确反映可见性、禁用态、选中态等真实状态;例如 disabled 按钮仍有 text,未显式设置 checked 的 checkbox 需用 is_selected() 判断。

直接用 get_attribute() 和 is_displayed() 组合判断最稳,别依赖 innerHTML 或 textContent 做状态推断。
为什么不能只靠 text 或 innerHTML 判断状态
元素的可见性、禁用态、选中态这些“状态”不等于“有没有文字”或“有没有标签内容”。比如一个 <button disabled>提交</button>,text 是“提交”,innerHTML 是“提交”,但实际不可点;又比如一个 checkbox 被 JS 设置为 checked 但没写 checked="checked",get_attribute("checked") 返回 null,而 is_selected() 才是 True。
常见错误现象:
- 脚本点不到按钮,报
ElementClickInterceptedException,但元素明明“看得见”——其实是is_displayed() == True但is_enabled() == False - 断言“复选框已勾选”失败,因为用了
get_attribute("checked")而不是is_selected() - 等待元素“出现”用
presence_of_element_located就结束,结果后续操作失败——它只管 DOM 存在,不管是否渲染完成或可交互
get_attribute() 该取哪些属性才反映真实状态
不是所有属性都适合做状态依据。优先取浏览器原生属性(attribute),而非 JS 属性(property)或计算样式:
- 表单控件禁用:用
get_attribute("disabled")(返回"disabled"或None),不要用get_attribute("aria-disabled")—— 后者是辅助属性,可能被误设或缺失 - 输入框值变化:用
get_attribute("value"),不是text——text对input永远为空,除非是contenteditable - 链接目标:用
get_attribute("href"),不是get_attribute("src")—— 后者属于img、script等标签 - 自定义状态标识:优先用
data-属性,如get_attribute("data-status"),比 class 名稳定(class 可能含多个值且顺序不定)
is_displayed() 和 is_enabled() 的真实行为边界
这两个方法底层调用浏览器驱动的真实 DOM 查询,但有明确限制:
-
is_displayed()返回False的情况包括:CSSdisplay: none、visibility: hidden、父元素隐藏、元素尺寸为 0×0、被其他元素完全遮盖(z-index 覆盖) -
is_enabled()只检查disabled属性和type="submit"等固有禁用逻辑,对 JS 动态加的pointer-events: none或 class 控制的禁用无效 - 二者都不检测
aria-hidden="true"或aria-disabled="true"—— 这些是给读屏器用的,不影响 Selenium 行为 - 如果元素在 iframe 里,必须先
switch_to.frame(),否则一律返回False或抛异常
动态元素状态等待的实操要点
状态变化常伴随异步渲染(如 Vue 的 v-if、React 的条件渲染),不能只等元素存在:
- 等待“变为可点击”:用
element_to_be_clickable,它同时检查is_displayed()和is_enabled() - 等待“变为未选中”:自己写 expected condition,例如
lambda d: not el.is_selected(),别用invisibility_of_element—— 那是针对消失,不是取消选中 - 等待自定义状态变更:比如
data-loading="true"→data-loading="false",用text_to_be_present_in_element_attribute,传入("data-loading", "false") - 避免轮询 sleep:Selenium 的显式等待自带重试机制,比
time.sleep(1); el.get_attribute(...)更可靠也更省资源
真正容易被忽略的是:很多“状态”根本不在 HTML 属性里,而是由 CSS 类 + JS 行为共同决定的(比如 btn btn--loading 类控制 spinner 显示)。这种场景下,得结合 get_attribute("class") 解析类名,再配合理解业务逻辑,而不是指望一个方法包打全部。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











