Skip to content

Web CSS Selector 元素定位教程

目标:在自动化 / 抓取脚本中以稳定、简洁、可维护方式定位网页元素。核心:优先稳定属性,避免脆弱结构链。

1. 基础语法

  • 标签:button input div
  • id:#loginForm
  • class:.btn .btn.primary
  • 多类:.tag.item.active
  • 组合:form#loginForm input.password
  • 子代:ul.list > li.item > a.link
  • 后代:#app .nav .menu-item
  • 相邻兄弟:h2 + p
  • 通用兄弟:h2 ~ ul
  • 分组:.btn.primary, .btn.warning

示例:

html
<form id="loginForm">
  <input class="field account" name="account">
  <input class="field password" name="password" type="password">
  <button class="btn primary" data-testid="login-submit">登录</button>
</form>

推荐: #loginForm input[name="account"] button[data-testid="login-submit"]

1.1 从控制台获取元素 css selector

css selector 获取的selector: #VPContent > div > div > div.content > div > main > div

2. 属性选择器

  • 精确:[data-role="dialog"] input[type="password"]
  • 开头:input[name^="user_"]
  • 结尾:input[name$="_id"]
  • 包含:div[class*="toast"]
  • 多属性:button[data-action="save"][type="button"]
  • 存在:input[required] [aria-label]

示例:

html
<button data-action="save" data-testid="order-save" type="button">保存</button>

推荐: button[data-testid="order-save"]

3. 自定义与测试属性

优先使用:data-testid data-qa data-role aria-*
规范格式:模块-区域-元素(-动作) 示例: [data-testid="user-row-edit"] [data-testid="login-form-submit"]

4. 伪类(查询用)

  • :first-child :last-child
  • :nth-child(2) :nth-of-type(3)
  • :not(.disabled)
  • :where(.btn.primary)(降权辅助) 注意:自动化库有时不支持复杂伪类,优先常规选择器。

示例: ul.user-list > li:nth-child(1) .name

5. 策略优先级

  1. data-* / aria-* 稳定属性
  2. 语义唯一 id
  3. 组合属性(role + name + type)
  4. 类名(避免构建工具 hash)
  5. 结构关系(> + 相对父容器) 避免:深链 div > div > div > ... 、纯索引 li:nth-child(7)

6. 稳定写法对比

脆弱:div.container > ul > li:nth-child(3) > span.name
改进:li[data-id="u123"] .name

脆弱:.sc-a1b2c3.hash-btn
改进:button[data-testid="user-row-edit"]

7. 列表 / 表格模式

html
<table data-grid="orders">
  <tbody>
    <tr data-row-id="o456">
      <td data-col="status">已支付</td>
      <td data-col="action"><button data-testid="order-row-refund">退款</button></td>
    </tr>
  </tbody>
</table>

行:table[data-grid="orders"] tr[data-row-id="o456"]
状态单元:table[data-grid="orders"] tr[data-row-id="o456"] td[data-col="status"]
按钮:button[data-testid="order-row-refund"]

8. 登录示例

html
<form id="loginForm">
  <input name="account">
  <input name="password" type="password">
  <button data-testid="login-submit">登录</button>
</form>

账号:#loginForm input[name="account"]
提交:button[data-testid="login-submit"]

9. 动态元素

  • 首选稳定容器内相对定位:div[data-panel="toast"] .message
  • 列表新增:ul[data-list="tasks"] li[data-id="t123"] .edit
  • 避免使用出现顺序索引定位

10. 调试技巧

  • DevTools Console:document.querySelectorAll('selector')
  • 验证唯一:长度 === 1
  • 临时高亮: document.querySelectorAll('[data-testid="login-submit"]').forEach(n=>n.style.outline='2px solid red')

11. 常见反模式

  • 复制深层自动生成 XPath → 转 CSS
  • 使用占位符 placeholder 作为唯一定位
  • 依赖动态 innerText(多语言 / 文案调整)
  • 过度链式:#app > div > div > ul > li > a > span

12. 推荐速查

按钮(测试属性):button[data-testid="xxx"]
输入框(名称):input[name="xxx"]
行元素:tr[data-row-id="xxx"]
列表项:ul[data-list="users"] li[data-id="u123"]
复选框:input[type="checkbox"][name="agree"]
模糊名称:input[name^="user_"]
必填:form#profile input[required]

13. 页面对象示例(伪代码)

class LoginPage { account = '#loginForm input[name="account"]' password = '#loginForm input[name="password"]' submit = 'button[data-testid="login-submit"]' }

14. 审查与维护

  • 推动前端加 data-testid
  • 超过 3 层层级重构
  • 定期扫描失效选择器
  • 统一命名规范:模块-区域-元素(-动作)

15. 选择器优化流程

初版运行 → 收集不稳定 → 替换为稳定属性 → 抽象页面对象 → 定期复查

16. 总结

  • 优先自定义稳定属性
  • 精简,少用深层结构
  • 组合属性优于位置索引
  • 避免业务文案依赖
  • 持续维护与命名规范并行

结束。将以上模式直接套用并推动前端暴露测试属性,可显著降低维护成本。

需要更多帮助?

如果您的问题未在此找到答案,请联系技术支持或查看官方文档获取更多帮助。