元素定位演示 · CSS 选择器定位

系统学习 By.CSS_SELECTOR 的核心语法、实操示例与最佳实践

首页 定位导航

By.CSS_SELECTOR 定位导读

By.CSS_SELECTOR 是 Selenium 中功能最强大、语法最灵活的元素定位方式,利用浏览器原生 CSS 选择器引擎进行匹配(与写 <style> 里的选择器完全一样)。它能覆盖 ID、CLASS、TAG、属性、层级、伪类等任意组合:#username(id)、.btn.primary(多 class 组合,这是 By.CLASS_NAME 做不到的)、input[name='password'](属性)、ul.menu > li:first-child(层级+伪类)、a[href^='/api'](属性前缀匹配)。与 XPath 相比,CSS 选择器写法更简洁、性能更好,但有一个硬伤:无法向上查找父元素、不支持文本函数(如 text()、contains())— 遇到这两种场景请换 By.XPATH。

By.CSS_SELECTOR 快速入门
掌握核心语法与定位策略
语法示例
find_element / find_elements 用法
实操练习
交互式练习区实时反馈
By.CSS_SELECTOR

⑧ CSS 选择器定位

浏览器原生支持,语法简洁,通常比 XPath 更快
CSS 选择器定位语法:
单个元素 (find_element)
driver.find_element(By.CSS_SELECTOR, "html body div.container div.product-list div.product-card") (① 绝对路径
🗂️ 绝对路径:从 html 根一路写到目标
以 html 为起点、一路写到目标元素,就是绝对路径(从根节点写起)——起点决定性质,只要从 html 写起就是绝对路径,与段间用什么分隔符无关。段间分隔符有两种:空格代表“后代”(中间允许隔着其他层级);> 代表“直接子代”(必须紧挨着下一层):
▼ 宽松版(全用空格,后代选择器):层间允许有中间包裹
html body div.container div.product-list div.product-card
① html body → 根 + body
② div.container → class=container 的 div(body 的任意后代)
③ div.product-list → 其后代 div(class=product-list,层间可包多层)
④ div.product-card → 目标元素(product-list 的任意后代)
▼ 严格逐层版(每层用 >,子代选择器):中间多一层立即失败
html > body > div.container > div.product-list > div.product-card
① html > body → body 必须是 html 的直接子(永远成立)
② body > div.container → div.container 必须是 body 的直接子,中间包一层就失效
③ div.container > div.product-list → 必须紧挨着下一层,不能跳过任何 div/section
④ div.product-list > div.product-card → 必须是 product-list 的直接子,否则匹配失败
▼ 混用版(空格与 > 自由组合):同一条路径里每一跳按需选分隔符
html > body > div.container div.product-list > div.product-card
① html > body > div.container → 用 > 收紧:container 必须是 body 的直接子(页面主容器不会漂)
② div.product-list → 用空格放宽:container 和 product-list 之间可能被 React/Vue 多包一层,空格不怕
③ > div.product-card → 再用 > 收紧:product-card 必须是 list 的直接子,避免误命中嵌套卡片
💡 实战思路:结构稳定、不会跳层的地方用 >(精准无歧义);结构可能被框架渲染多包一层的地方用空格(抗脆弱)。两种分隔符同一条路径里可以混用,哪一段需要收紧就用 >,哪一段允许跳层就用空格,完全自由组合。
💡 关键:是不是绝对路径只看起点(是否从 html 写起);空格与> 只决定每一跳能跨多深:
div.container div.product-card → 空格 = 后代选择器(任意层级都行) div.container > div.product-card → > = 子选择器(必须是直接下一层)
空格 后代选择器:只要在祖先内部就命中,跨多少层都可以。中间再包几层 div / ul / li 都不影响
> 子选择器:只找紧挨着的下一层直接子元素,中间多一层就匹配失败
举例 div a 能命中 div 里所有层级的 a;div > a 只命中 div 的直接子 a,包在 span 里的 a 不算
提示 上面这条全用空格,属于宽松版绝对路径(层间允许有中间包裹);真正严格逐层(等价 XPath 的 /html/body/…,中间多一层立即失败)要每一跳都用 >:
html > body > div.container > div.product-list > div.product-card → 严格逐层版
⚠️ 绝对路径的致命问题:
• DOM 结构一变(中间加个 div),整条路径作废
• 前端框架(React/Vue)渲染时结构不稳定
• 实战中几乎不用 CSS 绝对路径,更推荐 id / class / 属性选择器
)
driver.find_element(By.CSS_SELECTOR, "div.product-list > div.product-card") (② 相对路径
📍 相对路径:从中间特征元素开始
跳过 html body,直接从页面中某个有特征的祖先元素开始写,用 空格 表示后代、> 表示直接子级:
div.product-list div.product-card → 空格 = 后代(不限制层级) div.product-list > div.product-card → > = 直接子级(只找下一层)
✅ 比绝对路径短,抗 DOM 结构变动
✅ > 子选择器精准、性能好
💡 相对路径 + class/id 组合是实战首选
💚 推荐指数:★★★★☆ —— 比绝对路径好用得多
)
driver.find_element(By.CSS_SELECTOR, "#userName") (③ id 选择器
🔢 id 选择器 —— 最稳定最快
以 # 开头,后跟元素的 id 属性值,全局唯一:
#userName → id="userName" 的元素
#login-btn → id="login-btn" 的按钮
✅ 元素 id 全局唯一(HTML 规范)
✅ 浏览器原生优化,速度最快
✅ 可读性最高,一看就知道定位什么
⚠️ 如果前端框架动态生成 id(如 Vue 的 hash),每次刷新都会变,此时别用 id。
)
driver.find_elements(By.CSS_SELECTOR, ".product-card") (④ class 选择器
📦 class 选择器 —— 同一类批量定位
以 . 开头,后跟元素的 class 属性值:
.product-card → 所有 class=product-card
div.product-card → 限定标签:div 且 class=product-card
✅ 同一 class 可能有多个元素 → 适合 find_elements
✅ 前端组件化常用 class,稳定性较好
❌ 别用纯 class 做 find_element——返回第一个,页面多个时可能找错
)
driver.find_element(By.CSS_SELECTOR, "input[name='email']") (⑤ 属性选择器
🎯 属性选择器 —— 最灵活的精确武器
用 [属性='值'] 精确匹配元素的 任意 HTML 属性——包含 id 和 class 属性。它们本身就是属性,同样能用这种写法匹配:
input[name='email'] → name 精确等于 'email' div[data-category='book'] → 自定义 data-* 属性精确匹配
🆕 重点:id / class 也能这样写——简写版只是语法糖
#userName → 简写(id 选择器) [id='userName'] → 完整版(属性选择器)← 完全等价 .product-card → 简写(class 选择器) [class='product-card'] → 完整版(属性选择器)← 完全等价(但 class 多值时要小心)
✅ 能匹配任意属性(name / type / href / data-* / id / class…)
💡 简写版(# / .)更短更好读;属性选择器版更灵活(对 id 也能用 *=、^=、$= 等通配符——详见 ⑦ 部分属性值选择器)
⚠️ class 用 [class='product-card'] 是全值精确匹配——如果一个元素有 class="product-card active"(两个 class),这条会匹配失败;要兼容多值应写 [class~='product-card'](~= 单词匹配),或直接用简写 .product-card
)
driver.find_element(By.CSS_SELECTOR, "input[name]") (⑥ 属性名称选择器
📎 属性名称选择器 —— 只检查有没有
只写属性名不写值 [name] → 只要存在这个属性就算匹配:
input[name] → 任何有 name 属性的 input
a[target] → 任何有 target 属性的链接
✅ 适用于属性值动态变化的场景
⚠️ 匹配范围更广,可能匹配多个,建议配合标签限定或 find_elements
)
driver.find_element(By.CSS_SELECTOR, "a[href*='selenium']") (⑦ 部分属性值选择器
🔖 部分属性值匹配 —— 通配技巧
三种通配符,用于属性值不完全确定的场景:
a[href*='selenium'] → *= 包含(href 里有 selenium) a[href^='https'] → ^= 开头(href 以 https 开头) a[href$='.pdf'] → $= 结尾(href 以 .pdf 结尾) a[href~='download'] → ~= 单词(href 空格分隔含 download) a[href|='/api'] → |= 连字符(href 以 /api 或 /api- 开头)
💡 *= 最常用(包含匹配),类似 SQL 的 LIKE '%selenium%'
💡 ^= 和 $= 用于前缀/后缀固定的场景
)
driver.find_element(By.CSS_SELECTOR, "a") (⑧ 标签名选择器
🏷️ 标签名选择器 —— 最基础也最危险
直接写 HTML 标签名 a / input / div / button,匹配页面上所有该标签:
a → 页面上所有链接(可能几百个!)
input → 所有 input 元素
button → 所有按钮
✅ 简单快速,适合 find_elements 批量获取
❌ 页面元素多时容易找错第一个,搭配属性限定更稳
💡 input[type='checkbox'] 就是标签名 + 属性限定的好例子
)
driver.find_element(By.CSS_SELECTOR, ".product-card:nth-child(3)") (⑨ 伪类选择器
🔢 伪类选择器 —— 按位置/状态选
用 :伪类 按位置、状态、结构筛选元素:
.product-card:nth-child(3) → 第 3 个 product-card li:first-child → 列表第一项 li:last-child → 列表最后一项 tr:nth-of-type(odd) → 奇数行 input:checked → 选中的 checkbox/radio a:hover → 悬停状态(定位时不用) input:focus → 聚焦状态
⚠️ nth-child 是所有兄弟节点中排第 n 个,不限标签
💡 nth-of-type 只看同标签兄弟,更精准
💡 Selenium 定位时别用 :hover / :focus 等动态状态伪类
)
driver.find_element(By.CSS_SELECTOR, "div.card + div.action") (⑩ 兄弟选择器
👥 兄弟选择器:+ 紧邻、~ 全部
同级元素之间的选择,用 + 和 ~:
div.card + div.action → + 紧邻兄弟:必须紧挨在后面 div.card ~ div.action → ~ 全部兄弟:后面所有同级的都行
✅ + 更严格,只找紧邻的下一个兄弟
✅ ~ 更宽松,后面所有同级兄弟都匹配
💡 两个选择器都只看后面的兄弟,前面的选不到
💚 典型场景:勾选框后面的 label、卡片后面的操作按钮
)
多个元素 (find_elements)
driver.find_elements(By.CSS_SELECTOR, "html body div.container div.product-list div.product-card") (① 绝对路径)
driver.find_elements(By.CSS_SELECTOR, "div.product-list > div.product-card") (② 相对路径)
driver.find_elements(By.CSS_SELECTOR, "#userName") (③ id 选择器)
driver.find_elements(By.CSS_SELECTOR, ".product-card") (④ class 选择器)
driver.find_elements(By.CSS_SELECTOR, "input[name='email']") (⑤ 属性选择器)
driver.find_elements(By.CSS_SELECTOR, "input[name]") (⑥ 属性名称选择器)
driver.find_elements(By.CSS_SELECTOR, "a[href*='selenium']") (⑦ 部分属性值选择器)
driver.find_elements(By.CSS_SELECTOR, "a") (⑧ 标签名选择器)
driver.find_elements(By.CSS_SELECTOR, ".product-card:nth-child(3)") (⑨ 伪类选择器)
driver.find_elements(By.CSS_SELECTOR, "div.card + div.action") (⑩ 兄弟选择器)
特点:浏览器原生支持,语法简洁,定位速度通常比 XPath 更快。常用符号:^= 开头 $= 结尾 *= 包含。
实操练习:By.CSS_SELECTOR → 查看 Selenium 代码与执行结果
DemoShop
购物车
热门推荐
Selenium 速通
书籍类 · 包邮
¥199
测试开发架构师
精选 · 书籍类
¥499
Appium 移动端
热门 · 视频类
¥159
接口自动化
视频类 · 限时特惠
¥299
关于我们 联系客服 帮助中心 © DemoShop 示例商城

商品卡片列表(CSS 选择器演示)

Python 自动化实战
Selenium + Pytest 全解
¥299
接口自动化高级篇
Requests + Allure 报告
¥399
性能测试 JMeter
从入门到压测实战
¥199
Appium 移动端测试
Android + iOS 双端
¥159
面试通关宝典
软件测试高频 300 题
¥99
CSS 选择器实战技巧
  • ID 选择器:#idValue,Selenium 首选定位方式;CSS 中 #id 等价于 By.ID,比 XPath 更简洁高效。
  • 多 class:.product-card.featured 需同时包含两个 class;注意 .a.b(多类同时存在)≠ .a .b(后代选择器)。
  • 属性匹配:[attr='val'] 完全等于,[attr*='val'] 包含子串,[attr^='pre'] 开头匹配,[attr$='end'] 结尾匹配,[attr~='w'] 空格分隔的词中包含。
  • 层级关系:空格表示后代,> 表示直接子元素,+ 表示相邻兄弟,~ 表示后续所有兄弟;搭配 :first-child / :last-child / :nth-child(n) 可精确定位到特定位置。
定位后操作效果展示区域
本区域用于展示:使用 Selenium / JS 定位到上方元素后,执行「点击 / 输入 / 提交」等操作的真实反馈结果。

关于我们

Python 自动化测试学习平台是一个面向软件测试工程师、开发人员及在校学生的交互式在线学习平台,专注于 Selenium WebDriver 与 Python unittest 自动化测试技能的教学与实践。

我们以"理论 + 实战 + 可交互演示"为核心特色,将八种常规元素定位和Javascript定位、元素操作、自动化测试工具、单元测试、测试模型等知识体系拆分为模块化课程,每个模块都配有可点击、可输入、可运行的模拟练习页面。

平台致力于降低自动化测试的入门门槛,让学习者从"看懂代码"到"动手实操",逐步掌握企业级自动化测试框架的设计与落地能力。

联系方式

📧邮箱:lq@selenium-auto-test.com

📞电话:0755-12345678

📍地址:深圳

💬微信公众号:Selenium自动化测试

🐙GitHub:github.com/selenium-auto-test

免责声明

1. 本平台所有示例代码、演示页面及教程内容均仅供学习交流使用,不构成任何商业推广或技术服务承诺。

2. 平台中的 Selenium API 描述、Python 语法说明均以官方文档为准,如有版本差异请以对应官方文档为准。

3. 学习者在实际项目中应用平台所学内容时,应结合自身项目环境进行充分测试,本平台不对因直接使用示例代码而产生的任何直接或间接损失承担责任。

4. 本平台所引用的第三方库(Selenium、ChromeDriver、unittest 等)版权归其各自作者及维护者所有。

5. 如涉及版权问题或内容建议,请及时通过联系方式与我们沟通,我们将第一时间处理。