4、元素定位(上):ID定位、Name定位、Class Name定位、Tag Name定位、Link Text定位
各位同学,欢迎来到元素定位的实战环节。
说实话,做自动化测试这么多年,我见过太多新手一上来就卡在「找元素」这一步。脚本写好了,一运行,啪,报错——找不到元素。然后就开始怀疑人生,怀疑框架,甚至怀疑自己是不是不适合干这行。
别急。元素定位其实没那么玄乎。说白了,就是告诉浏览器:「嘿,帮我找到那个输入框,我要往里面打字。」
今天我们先讲五种最基础、最常用的定位方式。它们就像工具箱里的螺丝刀和扳手,简单,但你必须会用。
4.1 ID定位:最稳的定位方式
我个人习惯,只要元素有ID,我首选ID定位。为什么?因为ID在页面里是唯一的。就像每个人的身份证号,不会有第二个。
来看一个例子。假设页面上有个登录按钮:
<button id="login-btn">登录</button>
用Selenium怎么写?
driver.find_element(By.ID, "login-btn")
就这么简单。一行代码,搞定。
我在项目中遇到过一个问题:开发同事给两个不同的元素写了相同的ID。嗯,这其实违反了HTML规范,但现实就是这么魔幻。结果就是脚本时而找到这个,时而找到那个,跑得我头皮发麻。
4.2 Name定位:表单元素的标配
Name属性在表单里特别常见。你想想看,表单提交的时候,后端就是靠name来接收数据的。所以很多输入框、下拉框都有name属性。
举个例子:
<input type="text" name="username" placeholder="请输入用户名">
定位代码:
driver.find_element(By.NAME, "username")
注意一点:Name不像ID那样强制唯一。同一个页面里,多个元素可以有相同的name。比如一组单选按钮,它们的name通常是一样的。
我记得有一次做项目,一个注册页面有十几个输入框,全部都有name属性。我当时就笑了——这简直是给自动化测试量身定做的。一行xpath都不用写,全用name定位,干净利落。
4.3 Class Name定位:灵活但别太贪心
Class Name定位,说白了就是通过元素的CSS类名来找它。这个在样式丰富的页面上特别常用。
比如:
<div class="container main-content">内容区域</div>
定位代码:
driver.find_element(By.CLASS_NAME, "container")
这里有个坑,我必须提醒你:class_name只能传一个类名。上面那个元素有两个类名——container和main-content。如果你写成这样:
# 这样会报错!
driver.find_element(By.CLASS_NAME, "container main-content")
为什么?因为class_name定位不支持空格。它会把空格当成类名的一部分,但实际类名里没有空格。嗯,这个错误我犯过不止一次。
4.4 Tag Name定位:最不常用的定位方式
Tag Name定位,就是通过HTML标签名来找元素。比如input、div、button、a这些。
代码示例:
# 找到页面中第一个input元素
driver.find_element(By.TAG_NAME, "input")
# 找到页面中所有的div元素
driver.find_elements(By.TAG_NAME, "div")
说实话,这个定位方式我平时用得很少。为什么?因为一个页面里,input可能有几十个,div可能有上百个。你定位到第一个input,鬼知道它是哪个输入框?
那什么时候用呢?我个人经验是:当你需要批量获取某种类型的元素时。比如我想统计页面上有多少张图片:
images = driver.find_elements(By.TAG_NAME, "img")
print(f"页面上共有 {len(images)} 张图片")
或者我想获取页面上所有的链接:
links = driver.find_elements(By.TAG_NAME, "a")
for link in links:
print(link.get_attribute("href"))
你看,这种场景下,Tag Name定位反而很顺手。
4.5 Link Text定位:专治各种超链接
Link Text定位,顾名思义,就是通过链接的文本内容来定位。它只适用于<a>标签。
比如:
<a href="/login">点击登录</a>
定位代码:
driver.find_element(By.LINK_TEXT, "点击登录")
还有一个变种叫Partial Link Text,就是只匹配链接文本的一部分:
# 只要文本包含"登录"两个字就能匹配到
driver.find_element(By.PARTIAL_LINK_TEXT, "登录")
我在项目中遇到过一种情况:页面上有「登录」和「快速登录」两个链接。如果用Partial Link Text匹配「登录」,它会返回第一个匹配到的。如果你想要「快速登录」,那就得写更精确的文本,或者用索引。
4.6 五种定位方式对比
为了方便你记忆和选择,我整理了一个表格:
| 定位方式 | 适用场景 | 唯一性 | 推荐指数 |
|---|---|---|---|
| ID | 有ID属性的元素 | 高(理论上唯一) | ⭐⭐⭐⭐⭐ |
| Name | 表单元素(input、select等) | 中(可能重复) | ⭐⭐⭐⭐ |
| Class Name | 有CSS类名的元素 | 低(多个元素共享) | ⭐⭐⭐ |
| Tag Name | 批量获取同类元素 | 极低 | ⭐⭐ |
| Link Text | <a>标签链接 | 中(取决于文本是否唯一) | ⭐⭐⭐ |
4.7 实战建议
说了这么多,最后给你几条实战建议:
- 优先用ID——这是最稳的,没有之一。
- 其次用Name——表单页面特别好使。
- Class Name和Link Text——作为备选方案,心里有数就行。
- Tag Name——别用它来定位单个元素,那是给自己挖坑。
嗯,这五种定位方式,是自动化测试的入门基本功。你可能会觉得简单,但请相信我——把简单的招式练到极致,就是绝招。下一节我们会讲更高级的定位方式,比如XPath和CSS Selector。到时候你就知道,今天学的东西有多重要了。
好了,去打开你的浏览器,找个页面练练手吧。光看不练,等于白看。