元素定位教学 · 全方式详解

系统学习 ID / Name / Class / Tag / Link / XPath / CSS 七种定位方式,一页掌握 Selenium 元素定位核心技能

页面导读

本页面整合了属性定位、标签定位、链接定位、XPath 定位和 CSS 选择器定位的全部核心教学内容。每种定位方式都配有:定位语法说明、代码示例、可交互的练习区域。建议按顺序学习,从简单到复杂。

By.ID

① ID 属性定位

通过元素的 id 属性定位(唯一且稳定,优先使用)
定位语法:
单个元素 (find_element)
driver.find_element(By.ID, "user_account")(匹配第一个ID属性为user_account的元素)
driver.find_element(By.ID, "btn_id_submit")(匹配第一个ID属性为btn_id_submit的元素)
多个元素 (find_elements)
driver.find_elements(By.ID, "repeated_field")(理论上 ID 应唯一,不建议)
特点:id 在整个 HTML 页面中必须唯一,是最稳定、执行最快的定位方式,优先使用 find_element。
实操练习:By.ID → 查看 Selenium 代码与执行结果
定位后操作效果展示区域
本区域用于展示:使用 Selenium / JS 定位到上方元素后,执行「点击 / 输入 / 提交」等操作的真实反馈结果。

By.NAME

② Name 属性定位

通过元素的 name 属性定位(常用于表单元素)
定位语法:
单个元素 (find_element)
driver.find_element(By.NAME, "login_name")(匹配第一个name属性为login_name的元素)
driver.find_element(By.NAME, "csrf_token")(匹配第一个name属性为csrf_token的元素)
多个元素 (find_elements)
driver.find_elements(By.NAME, "hobby")(获取所有name属性为hobby的元素)
特点:name 属性常用于表单提交,一个页面中可能有多个同名元素,此时需用 find_elements 返回列表。
实操练习:By.NAME → 查看 Selenium 代码与执行结果
定位后操作效果展示区域
本区域用于展示:使用 Selenium / JS 定位到上方元素后,执行「点击 / 输入 / 提交」等操作的真实反馈结果。

By.CLASS_NAME

③ Class 属性定位

通过 class 属性定位(一组元素通常共用同一 class)
定位语法:
单个元素 (find_element)
driver.find_element(By.CLASS_NAME, "card-item")(匹配第一个class属性为card-item的元素)
driver.find_element(By.CLASS_NAME, "primary-btn")(匹配第一个class属性为primary-btn的元素)
多个元素 (find_elements)
driver.find_elements(By.CLASS_NAME, "card-item")(获取所有class属性为card-item的元素)
driver.find_elements(By.CLASS_NAME, "badge")(获取所有class属性为badge的元素)
注意:CLASS_NAME 只能传单个 class 名称,不能有空格。多 class 元素需用 CSS_SELECTOR。
实操练习:By.CLASS_NAME → 查看 Selenium 代码与执行结果

练习区 以下元素带有 demo- 前缀 class,与下方 demo-box 的 card-item / input-text / action-btn 完全隔离。

Python 入门
class=demo-item-card
Web 自动化
class=demo-item-card
接口测试
class=demo-item-card
Python 入门
class="card-item"
Web 自动化
class="card-item"
接口测试
class="card-item"
性能测试
class="card-item"
定位方式适用场景优点注意事项
By.ID元素具有唯一 id最快最稳定,优先使用id 必须唯一,动态 id 不适用
By.NAME表单元素有 name 属性常用于输入框/单选/复选可能不唯一,需 find_elements
By.CLASS_NAME一组相同样式的元素批量定位同类元素方便只能传单个 class,不能有空格
定位后操作效果展示区域
本区域用于展示:使用 Selenium / JS 定位到上方元素后,执行「点击 / 输入 / 提交」等操作的真实反馈结果。

By.TAG_NAME

④ 标签名定位

通过 HTML 标签名定位(通常返回多个元素)
定位语法:
单个元素 (find_element)
driver.find_element(By.TAG_NAME, "h1")(匹配第一个h1标签元素)
driver.find_element(By.TAG_NAME, "title")(匹配第一个title标签元素)
多个元素 (find_elements)
driver.find_elements(By.TAG_NAME, "a")(获取所有a标签元素)
driver.find_elements(By.TAG_NAME, "input")(获取所有input标签元素)
driver.find_elements(By.TAG_NAME, "li")(获取所有li标签元素)
特点:标签名定位常用于批量获取同类元素,绝大多数场景配合 find_elements 使用。
实操练习:By.TAG_NAME → 查看 Selenium 代码与执行结果
📦 电商后台 · 商品管理页面
商品分类: 手机数码 家用电器 服装鞋帽 食品饮料 美妆护肤
商品图 商品名称 分类 价格 库存 操作
iPhone 15 iPhone 15 Pro Max 手机数码 ¥9,999 128
MacBook MacBook Pro 14" 家用电器 ¥14,999 56
AirPods AirPods Pro 2 手机数码 ¥1,899 8
📊 运营数据
  • 总商品数 1,286 ▲ 较上周 +12%
  • 今日新增 23 ▲ 较昨日 +8%
  • 待上架 15 ▼ 较昨日 -3
  • 缺货预警 8 ⚠ 需尽快补货

💡 使用 By.TAG_NAME, "table" 定位整个商品表格,用 "tr" 获取每行数据。

💡 使用 By.TAG_NAME, "img" 获取所有商品图片,用 "button" 批量点击编辑。

标题标签(h1~h6)

H1 - 一级标题

H2 - 二级标题

H3 - 三级标题

段落标签(p)

段落 1:第一个 p 标签,可用 find_element 定位或者用 find_elements 获取列表加上索引 0 定位。

段落 2:第二个 p 标签,可用 find_elements 获取列表加上索引 1 定位。

段落 3:第三个 p 标签,可用 find_elements 获取列表加上索引 2 定位。

列表标签(ul/ol/li)

  • 无序列表项 A - 第 1 个 li
  • 无序列表项 B - 第 2 个 li
  • 无序列表项 C - 第 3 个 li
  1. 有序列表项 ①
  2. 有序列表项 ②
  3. 有序列表项 ③

图片标签(img)

示例图片

表格标签(table/tr/td/th)

序号 课程名称 标签名 说明
1Selenium 基础tr / td表格行与单元格
2元素定位tr / td用 XPath 定位表格
3元素操作tr / td表格操作场景
标签定位使用提示
  • 返回多个:同一标签名往往对应多个元素,优先使用 find_elements() 返回列表。
  • 组合使用:先通过 ID/class 定位父元素,再在父元素下通过 tag_name 定位会更精确。
  • 常见场景:获取所有链接 a、所有输入框 input、所有按钮 button。
定位后操作效果展示区域
本区域用于展示:使用 Selenium / JS 定位到上方元素后,执行「点击 / 输入 / 提交」等操作的真实反馈结果。



By.XPATH

⑦ XPath 定位

XML 路径语言,支持路径/属性/文本/轴等复杂定位
XPath 定位语法:
单个元素 (find_element)
driver.find_element(By.XPATH, "/html/body/div[1]/header/h1")(① 绝对路径
🗂️ 绝对路径:从根到目标,一步不差
XPath 里以 / 开头就是绝对路径,从 /html 根节点出发,逐层下钻到目标元素:
/html/body/div[1]/form[2]/div[3]/input
① /html → 根节点
② /body → body 直接子
③ /div[1] → 第 1 个 div 直接子
④ /form[2] → 第 2 个 form 直接子
⑤ /div[3] → 第 3 个 div 直接子
⑥ /input → 目标元素
⚠️ 绝对路径的致命问题:
• DOM 结构一变(中间加个 div 或序号变了),整条路径作废
• 不同浏览器渲染可能微调 DOM 层级
• 前端框架(React/Vue/Angular)渲染时结构不稳定
• 实战中 95%+ 不用绝对路径,除非页面结构完全固定
)
driver.find_element(By.XPATH, "//input")(② 相对路径
📘 相对路径(//)—— 从当前节点全局搜索
📖 相对路径是什么?
以 // 开头,表示"从当前节点往任意深度跳",不要求从根逐层下钻。相当于"全局搜索",找到第一个匹配就返回。
//input → 页面第一个 input
//form//input → form 下任意深度的 input
//*[@id='userName'] → 任意标签 id=userName
💪 相对路径的优势(为什么 95%+ 用它)
✅ 抗 DOM 变化:中间加/减 div 不影响定位
✅ 语法简洁://input 仅需标签名即可定位
✅ 浏览器兼容:不受不同浏览器渲染层级差异影响
✅ 框架友好:React/Vue 动态渲染也不怕
⚠️ 使用要点 & 常见陷阱
① // 搜索全页面://input 取第一个,多个 input 时加索引或属性
② 性能略差:// 比 / 慢(全局遍历),现代浏览器差异可忽略
③ 别嵌套 //://div//span//a 合法但可读性差
④ 多用属性限定://input[@id='x'] 比 //input 稳定得多
💡 实战最佳实践://tag[@id='xxx'] 或 //button[text()='提交']
🔀 // 和 / 混用 —— 核心规则
// 和 / 可以在同一条表达式里混用!每一步独立选择层级方式:
/html/body//form[@id='x']/div//input[@name='y']
↑ 根 ↑ 跳层 ↑ 直接子 ↑ 跳层
① /html/body 从根逐层下到 body(绝对)
② //form 从 body 任意深度跳层找 form(相对)
③ /div form 的直接子 div(逐层)
④ //input div 下任意深度跳层找 input(相对)
✅ 不是"要么全 // 要么全 /",每一段步长自由选择。
)
driver.find_element(By.XPATH, "(//input)[2]")(③ 元素索引
🔢 元素索引 (//标签)[n]
当 //标签 匹配多个元素时,用 [n] 取第 n 个,下标从 1 开始:
(//input)[1] → 第一个 input(等同 //input)
(//input)[2] → 第二个 input
(//input)[last()] → 最后一个 input
✅ 注意是 圆括号 括住 //标签 再加 [n],不是 //标签[n](后者含义不同)。
⚠️ (//input)[0] 是错的!XPath 下标从 1 开始,不是 0。
⚠️ 索引在动态页面不稳定,DOM 顺序一变就取错元素。
)
driver.find_element(By.XPATH, "//input[@id='userName']")(④ 属性
🏷️ 属性选择:最稳定的定位方式
用 [@属性='值'] 筛选元素,实战首选:
//input[@id='userName'] → id 最稳定,优先用
//input[@name='email'] → name 次之
//input[@type='password'] → type 也可
//button[@class='primary'] → class 不太稳定(多 class 问题)
✅ 优先级:@id > @name > @data-* > @type > @class
⚠️ class 多值时 [@class='btn primary'] 要全写 → 用 contains。
⚠️ @id 在 Vue/React 动态渲染时可能变化(如 el-123),注意检查。
)
driver.find_element(By.XPATH, "//div[contains(@class,'demo')]")(⑤ 模糊属性值
🔤 模糊属性值:starts-with + contains
① starts-with(@属性, '前缀'):匹配属性值以某字符串开头
//input[starts-with(@type,'pass')] → type="password" 能匹配
//div[starts-with(@id,'el-')] → Vue 动态 id 通用匹配
② contains(@属性, '关键字'):匹配属性值包含某字符串(最常用)
//div[contains(@class,'btn')] → 能匹配 class="btn btn-primary"
//a[contains(@href,'selenium')] → href 里有 selenium 的链接
✅ contains 比 starts-with 更灵活,是实战首选。
✅ contains(., '文字') 还能匹配元素的文本内容。
⚠️ 两个函数都大小写敏感,参数必须加引号。
⚠️ contains 可能匹配多个元素,建议配合 and 缩小范围。
)
driver.find_element(By.XPATH, "//button[normalize-space()='提交表单']")(⑥ 文本匹配
📝 文本匹配:精确 + 部分(contains)
① 精确匹配:[text()='xxx'] 或 [normalize-space()='xxx']
//button[text()='提交'] → 精确匹配
//button[normalize-space()='提交表单'] → 忽略前后空格,推荐
② 部分匹配:[contains(text(),'关键字')]
//a[contains(text(),'登录')] → 包含"登录"就能匹配
//button[contains(., '保存')] → 匹配整个节点内文本
✅ 部分匹配更灵活:文案变了但关键字保留的场景。
✅ contains(., '文字') 用 . 比 text() 范围更广。
⚠️ text() 只匹配直接子文本节点,子元素里的文本不算。
⚠️ 文本会变!国际化、A/B 测试都可能改文案,别在关键路径上依赖文本匹配。
)
driver.find_element(By.XPATH, "//div[@class='form-grid']/div[last()]")(⑦ 函数条件匹配
🧮 XPath 内置函数
XPath 提供多种内置函数,最常用的几个:
[last()] → 取最后一个同级元素
[position()=n] → 取第 n 个同级(等同 [n])
[last()-1] → 取倒数第二个
string-length(@id) → 属性值的字符串长度
✅ last() 特别实用——动态列表中取最后一项很方便。
⚠️ position() 依赖当前节点集顺序,复杂 XPath 中可能不符合预期。
)
driver.find_element(By.XPATH, "//*[@name='email' and @type='text']")(⑧ 逻辑运算符
🔗 and / or / not:多条件组合
用 and / or / not() 组合多个筛选条件:
//input[@name='email' and @type='text'] → 同时满足
//input[@type='text' or @type='password'] → 任一满足
//input[not(@disabled)] → 未禁用的 input
✅ and 是实战中最常用的——给 contains 加第二条件缩小范围。
⚠️ 不要用 && / ||,XPath 里是 and / or(英文单词)。
⚠️ not() 是函数不是运算符:[not(@disabled)],不能写 [!@disabled]。
)
driver.find_element(By.XPATH, "//label/following-sibling::input")(⑨ 轴定位
🧭 轴定位:全方向导航
轴(Axis)让你从当前元素向任意方向导航:
//label/following-sibling::input → label 后面的 input 兄弟
//input/preceding-sibling::label → input 前面的 label 兄弟
//td/ancestor::tr → td 的祖先 tr 行
//div/parent::form → div 的父 form
✅ following-sibling / preceding-sibling 最实用——处理表单项(label + input)绝配。
⚠️ 轴是 XPath 最强大但最少用的功能——90% 的场景 // + 属性就能搞定。
⚠️ 轴语法:节点/轴名::tag,双冒号 :: 别写成单冒号。
)
📘 两种写法模式:
基础写法(9 种纯技法):每条 XPath 只展示一种技法,便于理解;
复杂写法(多技法混合):把多种技法混在一条里(// + / + contains + and + 轴 + 函数),实战中 90%+ 的定位都这样写!
点击上面的「基础 XPath 定位」和「复杂 XPath 定位」按钮对比看效果。
多个元素 (find_elements) — 语法完全相同,返回 List 而非单个 WebElement
driver.find_elements(By.XPATH, "/html/body/div[1]/header/h1")(① 绝对路径)
driver.find_elements(By.XPATH, "//input")(② 相对路径)
driver.find_elements(By.XPATH, "(//input)[2]")(③ 元素索引)
driver.find_elements(By.XPATH, "//input[@id='userName']")(④ 属性)
driver.find_elements(By.XPATH, "//div[contains(@class,'demo')]")(⑤ 模糊属性值)
driver.find_elements(By.XPATH, "//button[normalize-space()='提交表单']")(⑥ 文本匹配)
driver.find_elements(By.XPATH, "//div[@class='form-grid']/div[last()]")(⑦ 函数条件匹配)
driver.find_elements(By.XPATH, "//*[@name='email' and @type='text']")(⑧ 逻辑运算符)
driver.find_elements(By.XPATH, "//label/following-sibling::input")(⑨ 轴定位)
特点:功能最强大,支持路径 / 属性 / 文本 / 函数 / 轴 / 逻辑运算符等复杂定位,是 Selenium 中最灵活的定位方式;但语法较复杂、不同浏览器渲染差异可能导致绝对路径失效,实战推荐相对路径 // + 属性组合。
实操练习:By.XPATH → 查看 Selenium 代码与执行结果
练习表单:form#demoXpathForm(仅用于 loc-practice-area)

示例表单(id="xpathForm")

XPath 实战技巧
  • 优先使用 相对路径 //,不推荐用 /html/body/div... 绝对路径。
  • 组合 @id/@name/@class/@type 等属性,多属性 and 更稳定。
  • 文本匹配:text()='xxx' 或 contains(text(),'xxx')。
  • 索引:(//...)[n],XPath 下标从 1 开始。
定位后操作效果展示区域
本区域用于展示:使用 Selenium / JS 定位到上方元素后,执行「点击 / 输入 / 提交」等操作的真实反馈结果。

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 定位到上方元素后,执行「点击 / 输入 / 提交」等操作的真实反馈结果。
driver.execute_script

⑨ JavaScript 定位

通过 execute_script 执行 JS,适合特殊场景与 Selenium 原生 API 无法覆盖的需求
JavaScript 定位语法:
通过 execute_script 执行 JS 定位
driver.execute_script("return document.getElementById('demo-js-username');") (getElementById)
driver.execute_script("return document.getElementsByName('demo-js-input')[0];") (getElementsByName)
driver.execute_script("return document.getElementsByClassName('demo-js-btn')[0];") (getElementsByClassName)
driver.execute_script("return document.getElementsByTagName('button')[0];") (getElementsByTagName)
driver.execute_script("return document.querySelector('.demo-js-card');") (querySelector)
driver.execute_script("return document.querySelectorAll('.demo-js-card');") (querySelectorAll)
特点:当 Selenium 原生定位方式受限时(如 Shadow DOM、iframe 嵌套、动态属性),可通过 execute_script 直接调用浏览器原生 JS API 定位元素。但可读性较差,调试不便。
实操练习:JavaScript 定位 → 查看 Selenium 代码与执行结果
会员中心 · 开通学习套餐 真实项目中常见的「套餐卡片 + 手机号录入 + 操作按钮」元素
真实页面元素

① 选择套餐(3 个 .demo-js-card,可被 querySelector / querySelectorAll 命中)

个人学习版 工具类 · 适合入门自测 ¥299¥399
视频速成版 视频类 · 碎片化学习 ¥159¥259

② 录入开通手机号(可被 getElementById 命中)

该输入框 id="demo-js-username",高级 JS 定位会用 execute_script 直接注入 value

JS 定位演示元素(execute_script 实战)

Selenium 脚本入门
JS 定位 — getElementById
¥299
DevTools 调试技巧
JS 定位 — getElementsByClassName
¥159
接口自动化进阶
JS 定位 — arguments 传参
¥399
批量元素操作实战
JS 定位 — querySelectorAll 批量
¥259
表单元素精准查询
JS 定位 — getElementsByName
¥199
JavaScript 定位实战技巧
  • getElementById:document.getElementById('id'),返回单个元素,速度最快。
  • getElementsByClassName:document.getElementsByClassName('btn'),返回 HTMLCollection(有 length、可索引),多个 class 空格分隔时只取一个。
  • getElementsByName:document.getElementsByName('username'),返回同名元素列表(常用于单选按钮组、表单控件),页面同名时返回全部匹配。
  • getElementsByTagName:document.getElementsByTagName('input'),返回页面上全部该标签的元素列表,配合父元素可做层级缩小搜索。
  • querySelector:document.querySelector('.cls'),CSS 选择器语法,返回首个匹配。
  • querySelectorAll:document.querySelectorAll('.cls'),返回 NodeList,需 list() 转换。
  • arguments 传参:arguments[0],向 execute_script 传递已定位的 WebElement。
  • 直接修改属性:.value = '...',绕过 send_keys 直接注入值。
定位后操作效果展示区域
本区域用于展示:使用 execute_script 定位到上方元素后,执行「点击 / 输入 / 提交」等操作的真实反馈结果。
综合对比

九种定位方式对比总结

一张表看懂所有定位方式的优缺点
定位方式语法适用场景优点缺点
By.IDBy.ID元素有唯一 id最快最稳定id 必须唯一
By.NAMEBy.NAME表单元素表单常用可能不唯一
By.CLASS_NAMEBy.CLASS_NAME同类元素批量批量定位方便只能单个 class
By.TAG_NAMEBy.TAG_NAME按标签名获取获取同类元素过于宽泛
By.LINK_TEXTBy.LINK_TEXTa 链接完整文本精准匹配仅 a 标签
By.PARTIAL_LINK_TEXTBy.PARTIAL_LINK_TEXTa 链接部分文本灵活模糊仅 a 标签
By.XPATHBy.XPATH任何复杂结构功能最强大语法稍复杂
By.CSS_SELECTORBy.CSS_SELECTOR任何元素简洁快速部分高级功能不支持
execute_scriptdriver.execute_script特殊场景(Shadow DOM / iframe / 动态属性)浏览器原生 API,灵活强大可读性差,调试不便

关于我们

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. 如涉及版权问题或内容建议,请及时通过联系方式与我们沟通,我们将第一时间处理。