Appearance
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
获取的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. 策略优先级
- data-* / aria-* 稳定属性
- 语义唯一 id
- 组合属性(role + name + type)
- 类名(避免构建工具 hash)
- 结构关系(> + 相对父容器) 避免:深链 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. 总结
- 优先自定义稳定属性
- 精简,少用深层结构
- 组合属性优于位置索引
- 避免业务文案依赖
- 持续维护与命名规范并行
结束。将以上模式直接套用并推动前端暴露测试属性,可显著降低维护成本。
需要更多帮助?
如果您的问题未在此找到答案,请联系技术支持或查看官方文档获取更多帮助。