Selenium 元素定位
Selenium 元素定位全攻略(2025 最新版)
元素定位 = 自动化操作的基石
掌握 8 种定位方式 + 高级技巧,99% 的元素都能精准命中!
一、8 种官方定位方式(By 类)
| 定位方式 | 语法 | 适用场景 | 速度 |
|---|---|---|---|
| ID | By.ID | 唯一 ID | ★★★★★ |
| NAME | By.NAME | 表单字段 | ★★★★ |
| CLASS_NAME | By.CLASS_NAME | 样式类 | ★★★ |
| TAG_NAME | By.TAG_NAME | 标签类型 | ★★★ |
| LINK_TEXT | By.LINK_TEXT | 完整链接文本 | ★★ |
| PARTIAL_LINK_TEXT | By.PARTIAL_LINK_TEXT | 部分链接文本 | ★★ |
| CSS_SELECTOR | By.CSS_SELECTOR | 推荐!灵活快速 | ★★★★★ |
| XPATH | By.XPATH | 最强大,复杂场景必备 | ★★★★ |
from selenium.webdriver.common.by import By
# 推荐写法(清晰、可读性强)
driver.find_element(By.ID, "username")
driver.find_element(By.CSS_SELECTOR, "input#username")
driver.find_element(By.XPATH, "//input[@name='username']")
二、推荐优先级(实战经验)
1. ID → 最快、最稳定
2. CSS Selector → 简洁、速度快
3. XPath → 复杂结构必备
4. Name → 表单常用
5. 其他 → 慎用(易变、慢)
三、CSS Selector 速查表(强烈推荐)
| 选择器 | 示例 | 说明 |
|---|---|---|
#id | #login | ID 选择器 |
.class | .btn-primary | 类选择器 |
tag | input | 标签 |
[attr] | [type="text"] | 属性 |
tag#id | input#username | 组合 |
tag.class | button.submit | |
> | div > span | 直接子元素 |
| 空格 | div span | 后代元素 |
nth-child(n) | li:nth-child(2) | 第 n 个 |
^= | [href^="https"] | 以…开头 |
$= | [href$=".pdf"] | 以…结尾 |
*= | [title*="登录"] | 包含 |
driver.find_element(By.CSS_SELECTOR, "input#kw") # 百度搜索框
driver.find_element(By.CSS_SELECTOR, "button[type=submit]") # 提交按钮
driver.find_element(By.CSS_SELECTOR, "ul li:nth-child(3)") # 列表第3项
四、XPath 速查表(复杂场景救星)
| 语法 | 示例 | 说明 |
|---|---|---|
//tag | //input | 任意位置的 input |
//tag[@attr='val'] | //input[@name='wd'] | 属性精确匹配 |
//tag[contains(@attr,'val')] | //a[contains(text(),'新闻')] | 包含文本 |
//tag[starts-with(@attr,'val')] | //img[starts-with(@src,'/static')] | 开头匹配 |
//tag[text()='登录'] | //button[text()='登录'] | 文本完全匹配 |
/ | /html/body/div | 绝对路径(不推荐) |
.. | //span/.. | 父元素 |
following-sibling::* | //label/following-sibling::input | 同级后面的元素 |
# 百度搜索框
driver.find_element(By.XPATH, "//input[@id='kw']")
# 包含“新闻”的链接
driver.find_element(By.XPATH, "//a[contains(text(), '新闻')]")
# 父元素 → 子元素 → 兄弟
driver.find_element(By.XPATH, "//label[text()='密码']/following-sibling::input")
五、相对定位(Selenium 4 新特性)
不用写复杂 XPath!用“相对于已知元素”定位
from selenium.webdriver.support.relative_locator import with_tag_name
# 找到已知元素
login_btn = driver.find_element(By.ID, "submit")
# 定位它上方的输入框
username = driver.find_element(with_tag_name("input").above(login_btn))
# 定位右侧的“忘记密码?”
forgot = driver.find_element(with_tag_name("a").to_right_of(login_btn))
支持方法:
above()/below()to_left_of()/to_right_of()near()(50px 内)
六、实战定位技巧
1. 动态 ID/CLASS?用父子结构 + 文本
# ID 每次变化:btn_12345 → 用父容器 + 文本
driver.find_element(By.XPATH, "//div[contains(@class,'login')]//button[text()='登录']")
2. iframe 内的元素?先切换
driver.switch_to.frame("iframe_id")
driver.find_element(By.ID, "inner_btn")
driver.switch_to.default_content() # 切回主文档
3. Shadow DOM?用 JS 穿透
element = driver.execute_script(
"return document.querySelector('my-component').shadowRoot.querySelector('#btn')"
)
4. 多个相同元素?用 find_elements
items = driver.find_elements(By.CSS_SELECTOR, "li.product")
for item in items:
print(item.text)
七、定位失败?排查清单
| 问题 | 检查点 |
|---|---|
NoSuchElementException | 1. 是否在 iframe? 2. 是否被 JS 动态加载?→ 加等待 3. 选择器写错?→ 浏览器 F12 验证 |
| 元素存在但不可点击 | element_to_be_clickable 等待 |
| 定位太慢 | 优先用 ID > CSS > XPath |
| 定位不稳定 | 避免绝对路径、动态 ID |
八、推荐工具:浏览器开发者工具
- Chrome DevTools → 右键 → Copy → Copy selector / XPath
- 插件推荐:
- SelectorsHub(自动生成 XPath/CSS)
- ChroPath
九、完整示例:登录 12306(复杂场景)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
wait = WebDriverWait(driver, 15)
try:
driver.get("https://kyfw.12306.cn/otn/resources/login.html")
# 切换到账号登录 tab
wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "账号登录"))).click()
# 输入用户名(iframe 内!)
iframe = wait.until(EC.presence_of_element_located((By.ID, "loginFrame")))
driver.switch_to.frame(iframe)
wait.until(EC.presence_of_element_located((By.ID, "J-userName"))).send_keys("your_username")
, "your_password")
driver.find_element(By.ID, "J-login").click()
finally:
driver.quit()
十、定位策略总结(金字塔)
ID
/ \
CSS Name
\ /
XPath
\ /
相对定位 + 文本
十一、定位练习网站
| 网站 | 用途 |
|---|---|
| https://the-internet.herokuapp.com | 各种控件练习 |
| http://httpbin.org/forms/post | 表单测试 |
| https://kyfw.12306.cn | 真实复杂场景 |
十二、一句话总结
好定位 = 稳定 + 快速 + 可维护 → 优先 ID → CSS → XPath → 相对定位
下一步:
想看 20 个真实网站定位案例(京东、淘宝、微博、抖音等)?
回复 cases 我立刻发你!
当前最佳实践:
webdriver-managerWebDriverWait+EC- CSS Selector 为主,XPath 为辅
- 避免
time.sleep()