系统学习 ID / Name / Class / Tag / Link / XPath / CSS 七种定位方式,一页掌握 Selenium 元素定位核心技能
本页面整合了属性定位、标签定位、链接定位、XPath 定位和 CSS 选择器定位的全部核心教学内容。每种定位方式都配有:定位语法说明、代码示例、可交互的练习区域。建议按顺序学习,从简单到复杂。
driver.find_element(By.ID, "user_account")(匹配第一个ID属性为user_account的元素)driver.find_element(By.ID, "btn_id_submit")(匹配第一个ID属性为btn_id_submit的元素)driver.find_elements(By.ID, "repeated_field")(理论上 ID 应唯一,不建议)driver.find_element(By.NAME, "login_name")(匹配第一个name属性为login_name的元素)driver.find_element(By.NAME, "csrf_token")(匹配第一个name属性为csrf_token的元素)driver.find_elements(By.NAME, "hobby")(获取所有name属性为hobby的元素)driver.find_element(By.CLASS_NAME, "card-item")(匹配第一个class属性为card-item的元素)driver.find_element(By.CLASS_NAME, "primary-btn")(匹配第一个class属性为primary-btn的元素)driver.find_elements(By.CLASS_NAME, "card-item")(获取所有class属性为card-item的元素)driver.find_elements(By.CLASS_NAME, "badge")(获取所有class属性为badge的元素)
以下元素带有 demo- 前缀 class,与下方 demo-box 的 card-item / input-text / action-btn 完全隔离。
| 定位方式 | 适用场景 | 优点 | 注意事项 |
|---|---|---|---|
| By.ID | 元素具有唯一 id | 最快最稳定,优先使用 | id 必须唯一,动态 id 不适用 |
| By.NAME | 表单元素有 name 属性 | 常用于输入框/单选/复选 | 可能不唯一,需 find_elements |
| By.CLASS_NAME | 一组相同样式的元素 | 批量定位同类元素方便 | 只能传单个 class,不能有空格 |
driver.find_element(By.TAG_NAME, "h1")(匹配第一个h1标签元素)driver.find_element(By.TAG_NAME, "title")(匹配第一个title标签元素)driver.find_elements(By.TAG_NAME, "a")(获取所有a标签元素)driver.find_elements(By.TAG_NAME, "input")(获取所有input标签元素)driver.find_elements(By.TAG_NAME, "li")(获取所有li标签元素)| 商品图 | 商品名称 | 分类 | 价格 | 库存 | 操作 |
|---|---|---|---|---|---|
| iPhone 15 Pro Max | 手机数码 | ¥9,999 | 128 | ||
| MacBook Pro 14" | 家用电器 | ¥14,999 | 56 | ||
| AirPods Pro 2 | 手机数码 | ¥1,899 | 8 |
💡 使用 By.TAG_NAME, "table" 定位整个商品表格,用 "tr" 获取每行数据。
💡 使用 By.TAG_NAME, "img" 获取所有商品图片,用 "button" 批量点击编辑。
H1 - 一级标题
H2 - 二级标题
H3 - 三级标题
段落 1:第一个 p 标签,可用 find_element 定位或者用 find_elements 获取列表加上索引 0 定位。
段落 2:第二个 p 标签,可用 find_elements 获取列表加上索引 1 定位。
段落 3:第三个 p 标签,可用 find_elements 获取列表加上索引 2 定位。
| 序号 | 课程名称 | 标签名 | 说明 |
|---|---|---|---|
| 1 | Selenium 基础 | tr / td | 表格行与单元格 |
| 2 | 元素定位 | tr / td | 用 XPath 定位表格 |
| 3 | 元素操作 | tr / td | 表格操作场景 |
find_elements() 返回列表。driver.find_element(By.LINK_TEXT, "返回首页")(匹配第一个"返回首页"链接)driver.find_element(By.LINK_TEXT, "Selenium 官方文档")(匹配第一个"Selenium 官方文档"链接)driver.find_elements(By.LINK_TEXT, "点击查看")(获取所有"点击查看"链接元素)driver.find_element(By.PARTIAL_LINK_TEXT, "关于")(匹配第一个包含"关于"的链接)driver.find_element(By.PARTIAL_LINK_TEXT, "教程")(匹配第一个包含"教程"的链接)driver.find_elements(By.PARTIAL_LINK_TEXT, "帮助")(获取所有含"帮助"的链接元素)driver.find_elements(By.PARTIAL_LINK_TEXT, "文档")(获取所有含"文档"的链接元素)下方导航栏包含多个链接,使用 PARTIAL_LINK_TEXT 可模糊匹配:
教程类链接(用"教程"可匹配全部):
<a> 标签,其他标签需用 XPath 或 CSS。driver.find_element(By.XPATH, "/html/body/div[1]/header/h1")(① 绝对路径
driver.find_element(By.XPATH, "//input")(② 相对路径
//input 仅需标签名即可定位//input 取第一个,多个 input 时加索引或属性// 比 / 慢(全局遍历),现代浏览器差异可忽略//div//span//a 合法但可读性差//input[@id='x'] 比 //input 稳定得多//tag[@id='xxx'] 或 //button[text()='提交']
driver.find_element(By.XPATH, "(//input)[2]")(③ 元素索引
//标签 匹配多个元素时,用 [n] 取第 n 个,下标从 1 开始://标签 再加 [n],不是 //标签[n](后者含义不同)。(//input)[0] 是错的!XPath 下标从 1 开始,不是 0。driver.find_element(By.XPATH, "//input[@id='userName']")(④ 属性
[@属性='值'] 筛选元素,实战首选:[@class='btn primary'] 要全写 → 用 contains。el-123),注意检查。driver.find_element(By.XPATH, "//div[contains(@class,'demo')]")(⑤ 模糊属性值
starts-with(@属性, '前缀'):匹配属性值以某字符串开头contains(@属性, '关键字'):匹配属性值包含某字符串(最常用)contains(., '文字') 还能匹配元素的文本内容。and 缩小范围。driver.find_element(By.XPATH, "//button[normalize-space()='提交表单']")(⑥ 文本匹配
[text()='xxx'] 或 [normalize-space()='xxx'][contains(text(),'关键字')]contains(., '文字') 用 . 比 text() 范围更广。text() 只匹配直接子文本节点,子元素里的文本不算。driver.find_element(By.XPATH, "//div[@class='form-grid']/div[last()]")(⑦ 函数条件匹配
last() 特别实用——动态列表中取最后一项很方便。driver.find_element(By.XPATH, "//*[@name='email' and @type='text']")(⑧ 逻辑运算符
and / or / not() 组合多个筛选条件:&& / ||,XPath 里是 and / or(英文单词)。not() 是函数不是运算符:[not(@disabled)],不能写 [!@disabled]。driver.find_element(By.XPATH, "//label/following-sibling::input")(⑨ 轴定位
节点/轴名::tag,双冒号 :: 别写成单冒号。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")(⑨ 轴定位)@id/@name/@class/@type 等属性,多属性 and 更稳定。text()='xxx' 或 contains(text(),'xxx')。(//...)[n],XPath 下标从 1 开始。driver.find_element(By.CSS_SELECTOR, "html body div.container div.product-list div.product-card") (① 绝对路径
driver.find_element(By.CSS_SELECTOR, "div.product-list > div.product-card") (② 相对路径
driver.find_element(By.CSS_SELECTOR, "#userName") (③ id 选择器
id 属性值,全局唯一:driver.find_elements(By.CSS_SELECTOR, ".product-card") (④ class 选择器
class 属性值:find_elementsfind_element——返回第一个,页面多个时可能找错driver.find_element(By.CSS_SELECTOR, "input[name='email']") (⑤ 属性选择器
id 和 class 属性。它们本身就是属性,同样能用这种写法匹配:class="product-card active"(两个 class),这条会匹配失败;要兼容多值应写 [class~='product-card'](~= 单词匹配),或直接用简写 .product-carddriver.find_element(By.CSS_SELECTOR, "input[name]") (⑥ 属性名称选择器
driver.find_element(By.CSS_SELECTOR, "a[href*='selenium']") (⑦ 部分属性值选择器
driver.find_element(By.CSS_SELECTOR, "a") (⑧ 标签名选择器
find_elements 批量获取input[type='checkbox'] 就是标签名 + 属性限定的好例子driver.find_element(By.CSS_SELECTOR, ".product-card:nth-child(3)") (⑨ 伪类选择器
driver.find_element(By.CSS_SELECTOR, "div.card + div.action") (⑩ 兄弟选择器
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") (⑩ 兄弟选择器)#idValue,Selenium 首选定位方式;CSS 中 #id 等价于 By.ID,比 XPath 更简洁高效。.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) 可精确定位到特定位置。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) ① 选择套餐(3 个 .demo-js-card,可被 querySelector / querySelectorAll 命中)
② 录入开通手机号(可被 getElementById 命中)
该输入框 id="demo-js-username",高级 JS 定位会用 execute_script 直接注入 value
document.getElementById('id'),返回单个元素,速度最快。document.getElementsByClassName('btn'),返回 HTMLCollection(有 length、可索引),多个 class 空格分隔时只取一个。document.getElementsByName('username'),返回同名元素列表(常用于单选按钮组、表单控件),页面同名时返回全部匹配。document.getElementsByTagName('input'),返回页面上全部该标签的元素列表,配合父元素可做层级缩小搜索。document.querySelector('.cls'),CSS 选择器语法,返回首个匹配。document.querySelectorAll('.cls'),返回 NodeList,需 list() 转换。arguments[0],向 execute_script 传递已定位的 WebElement。.value = '...',绕过 send_keys 直接注入值。| 定位方式 | 语法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| By.ID | By.ID | 元素有唯一 id | 最快最稳定 | id 必须唯一 |
| By.NAME | By.NAME | 表单元素 | 表单常用 | 可能不唯一 |
| By.CLASS_NAME | By.CLASS_NAME | 同类元素批量 | 批量定位方便 | 只能单个 class |
| By.TAG_NAME | By.TAG_NAME | 按标签名获取 | 获取同类元素 | 过于宽泛 |
| By.LINK_TEXT | By.LINK_TEXT | a 链接完整文本 | 精准匹配 | 仅 a 标签 |
| By.PARTIAL_LINK_TEXT | By.PARTIAL_LINK_TEXT | a 链接部分文本 | 灵活模糊 | 仅 a 标签 |
| By.XPATH | By.XPATH | 任何复杂结构 | 功能最强大 | 语法稍复杂 |
| By.CSS_SELECTOR | By.CSS_SELECTOR | 任何元素 | 简洁快速 | 部分高级功能不支持 |
| execute_script | driver.execute_script | 特殊场景(Shadow DOM / iframe / 动态属性) | 浏览器原生 API,灵活强大 | 可读性差,调试不便 |