4、元素定位(上):ID定位、Name定位、Class Name定位、Tag Name定位、Link Text定位

各位同学,欢迎来到元素定位的实战环节。

说实话,做自动化测试这么多年,我见过太多新手一上来就卡在「找元素」这一步。脚本写好了,一运行,啪,报错——找不到元素。然后就开始怀疑人生,怀疑框架,甚至怀疑自己是不是不适合干这行。

别急。元素定位其实没那么玄乎。说白了,就是告诉浏览器:「嘿,帮我找到那个输入框,我要往里面打字。」

今天我们先讲五种最基础、最常用的定位方式。它们就像工具箱里的螺丝刀和扳手,简单,但你必须会用。

4.1 ID定位:最稳的定位方式

我个人习惯,只要元素有ID,我首选ID定位。为什么?因为ID在页面里是唯一的。就像每个人的身份证号,不会有第二个。

核心原则: 有ID,就用ID。没有ID,再想别的办法。

来看一个例子。假设页面上有个登录按钮:

<button id="login-btn">登录</button>

用Selenium怎么写?

driver.find_element(By.ID, "login-btn")

就这么简单。一行代码,搞定。

我在项目中遇到过一个问题:开发同事给两个不同的元素写了相同的ID。嗯,这其实违反了HTML规范,但现实就是这么魔幻。结果就是脚本时而找到这个,时而找到那个,跑得我头皮发麻。

避坑指南: 我曾经因为ID重复,排查了整整一个下午。后来养成了一个习惯——拿到页面先检查ID是否真的唯一。用浏览器的开发者工具搜一下ID,看看返回几个结果。

4.2 Name定位:表单元素的标配

Name属性在表单里特别常见。你想想看,表单提交的时候,后端就是靠name来接收数据的。所以很多输入框、下拉框都有name属性。

举个例子:

<input type="text" name="username" placeholder="请输入用户名">

定位代码:

driver.find_element(By.NAME, "username")

注意一点:Name不像ID那样强制唯一。同一个页面里,多个元素可以有相同的name。比如一组单选按钮,它们的name通常是一样的。

小技巧: 如果页面里有多个同名的元素,find_element只会返回第一个。如果你想定位第二个、第三个,那就得用find_elements,然后通过索引来取。

我记得有一次做项目,一个注册页面有十几个输入框,全部都有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定位不支持空格。它会把空格当成类名的一部分,但实际类名里没有空格。嗯,这个错误我犯过不止一次。

重要提醒: 如果你需要同时匹配多个类名,请改用CSS选择器。后面我们会专门讲CSS定位,到时候你就知道怎么处理了。

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匹配「登录」,它会返回第一个匹配到的。如果你想要「快速登录」,那就得写更精确的文本,或者用索引。

经验之谈: Link Text定位虽然方便,但它对文本变化特别敏感。如果前端同事把「点击登录」改成了「立即登录」,你的脚本就挂了。所以,如果链接有ID,我建议优先用ID。没有ID的话,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。到时候你就知道,今天学的东西有多重要了。

好了,去打开你的浏览器,找个页面练练手吧。光看不练,等于白看。