2、元素定位(上):ID定位、Name定位、Class Name定位、Tag Name定位、Link Text定位、Partial Link Text定位
好,咱们正式开始接触Selenium的核心操作——元素定位。
说白了,自动化测试就是在模拟人操作浏览器。人用眼睛找按钮,Selenium用什么?用定位器。你告诉它「那个登录按钮在哪」,它才能去点。定位不准,后面全是白搭。
我个人习惯把元素定位比作「给网页元素贴标签」。标签贴得准,一找一个准;贴得模糊,就容易找错人。今天咱们先学六种最基础的贴标签方式。
2.1 ID定位:最快最稳的方式
ID在HTML里是唯一的。一个页面里,同一个ID只能出现一次。所以用ID定位,就像用身份证号找人,精准、高效。
核心要点:ID定位是Selenium所有定位方式中速度最快的。只要开发写了ID,我建议你优先用它。
语法很简单:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com/login")
# 用ID定位用户名输入框
username_input = driver.find_element(By.ID, "username")
username_input.send_keys("admin")
我在项目中遇到过一个问题:开发觉得ID写不写无所谓,结果整个页面就登录按钮没写ID。我找了半天,最后只能换别的定位方式。所以啊,前期跟开发沟通好,让他们把关键元素的ID都加上,能省你80%的定位时间。
小技巧:用浏览器开发者工具(F12)的Elements面板,直接看元素有没有id属性。有的话,优先用。
2.2 Name定位:ID的备胎
Name属性不像ID那么严格,它可以重复。同一个页面里,多个元素可以有相同的name。比如一组单选按钮,name通常是一样的。
用法跟ID几乎一样:
# 用Name定位密码输入框
password_input = driver.find_element(By.NAME, "password")
password_input.send_keys("123456")
嗯,这里要注意:如果页面上有多个相同name的元素,find_element只会返回第一个。你想找第二个?那就得用find_elements了,这个咱们后面会细讲。
我曾经在一个老项目里,发现开发把提交按钮的name写成了"submit"。结果页面里还有个隐藏的input也叫"submit"。我定位的时候老是点到隐藏的那个,气得我直接找开发改了ID。所以,Name定位虽然好用,但遇到重复值就得小心了。
2.3 Class Name定位:按样式找元素
Class Name,说白了就是CSS类名。一个元素可以有多个class,多个元素也可以共享同一个class。
举个例子:
<button class="btn btn-primary login-btn">登录</button>
这个按钮有三个class:btn、btn-primary、login-btn。你用其中任何一个都能定位到它。
# 用Class Name定位登录按钮
login_button = driver.find_element(By.CLASS_NAME, "login-btn")
login_button.click()
注意:如果class名里有空格,比如"btn btn-primary",你不能直接整个传进去。Selenium会把空格当成分隔符,认为你要匹配多个class。这时候应该用CSS选择器,后面会讲。
我刚开始学的时候,就踩过这个坑。一个按钮的class是"btn btn-danger",我直接传了"btn btn-danger"进去,结果报错。后来才知道,CLASS_NAME只接受单个class名。
2.4 Tag Name定位:最不推荐的方式
Tag Name就是HTML标签名,比如div、input、button、a这些。
你想想看,一个页面里有多少个div?几十上百个。你用Tag Name定位,就像在人群里喊「喂,那个穿衣服的!」——根本找不到具体的人。
# 找到页面中第一个input标签
first_input = driver.find_element(By.TAG_NAME, "input")
# 找到所有input标签
all_inputs = driver.find_elements(By.TAG_NAME, "input")
说实话,我工作中几乎不用Tag Name定位。唯一一次用,是在做页面结构验证的时候——我想确认页面里有没有某个标签存在。比如检查有没有video标签,来判断视频播放器是否加载成功。
我的建议:Tag Name只适合做「存在性检查」,不适合做「精准定位」。别用它来找按钮或输入框,你会后悔的。
2.5 Link Text定位:专治超链接
Link Text,就是标签里的文字内容。比如:
<a href="/register">立即注册</a>
你可以直接用「立即注册」这四个字来定位它:
# 用Link Text定位注册链接
register_link = driver.find_element(By.LINK_TEXT, "立即注册")
register_link.click()
这个方式有个好处:文字是给人看的,你一眼就知道这个链接是干嘛的。而且文字一般不会频繁变动,稳定性还不错。
不过要注意,Link Text必须完全匹配。链接文字是「立即注册」,你写「注册」就找不到。大小写也得一致。
2.6 Partial Link Text定位:模糊匹配
这个跟Link Text很像,但它是模糊匹配。你只需要写链接文字的一部分就行。
# 用Partial Link Text定位,只要包含"注册"就能找到
register_link = driver.find_element(By.PARTIAL_LINK_TEXT, "注册")
register_link.click()
为什么会需要这个?我遇到过一种情况:链接文字是动态生成的,比如「查看订单详情 - 20240101」,后面的数字每次都不一样。用Link Text没法写死,但用Partial Link Text,只匹配「查看订单详情」就能搞定。
使用建议:Partial Link Text虽然灵活,但匹配范围太广。如果页面上有两个链接都包含「注册」两个字,它只会返回第一个。这时候你得看看是不是该用更精确的定位方式了。
2.7 六种定位方式对比
为了方便你记忆和选择,我整理了一张表:
| 定位方式 | 定位依据 | 唯一性 | 速度 | 推荐指数 |
|---|---|---|---|---|
| ID | id属性 | 必须唯一 | 最快 | ★★★★★ |
| Name | name属性 | 可能重复 | 快 | ★★★★ |
| Class Name | class属性 | 可能重复 | 快 | ★★★ |
| Tag Name | 标签名 | 几乎不唯一 | 快 | ★ |
| Link Text | 链接文字 | 通常唯一 | 中等 | ★★★★ |
| Partial Link Text | 链接文字部分 | 可能重复 | 中等 | ★★★ |
2.8 实战小例子
咱们来写一个完整的例子,把今天学的六种方式都用上:
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome()
driver.get("https://example.com/login")
# 1. ID定位 - 用户名输入框
driver.find_element(By.ID, "username").send_keys("test_user")
# 2. Name定位 - 密码输入框
driver.find_element(By.NAME, "password").send_keys("pass123")
# 3. Class Name定位 - 登录按钮
driver.find_element(By.CLASS_NAME, "login-btn").click()
time.sleep(2)
# 4. Tag Name定位 - 检查页面是否有图片
images = driver.find_elements(By.TAG_NAME, "img")
print(f"页面共有 {len(images)} 张图片")
# 5. Link Text定位 - 点击"忘记密码"
driver.find_element(By.LINK_TEXT, "忘记密码").click()
# 6. Partial Link Text定位 - 点击"返回"
driver.find_element(By.PARTIAL_LINK_TEXT, "返回").click()
driver.quit()
这个例子虽然简单,但覆盖了今天所有的知识点。你可以自己跑一下,看看效果。
2.9 避坑指南
最后,分享几个我踩过的坑:
- 元素没加载完就定位:页面还没渲染完,你就去找元素,肯定找不到。解决方案是加等待,后面章节会详细讲。
- 大小写敏感:ID、Name、Class Name都是大小写敏感的。开发写的是"UserName",你写"username"就找不到。
- 动态ID:有些框架会生成动态ID,比如"user_12345",每次刷新都不一样。这时候别用ID定位,换别的。
- 隐藏元素:元素在DOM里存在,但被隐藏了(display:none)。用find_element能找到,但点击会报错。记得先判断元素是否可见。
好了,今天这六种定位方式,够你应付大部分场景了。下一节咱们继续讲剩下的几种定位方式,包括XPath和CSS选择器——这两个才是真正的杀手锏。
记住一句话:定位方式没有最好的,只有最合适的。多练、多试,你自然就知道什么时候该用哪个了。