3、元素定位详解(上):ID定位、Name定位、Class Name定位、Tag Name定位、Link Text定位

各位同学,咱们今天来聊聊自动化测试里最基础、也最核心的一环——元素定位。

说实话,我刚开始学Selenium的时候,觉得这玩意儿不就是找几个按钮嘛,有啥难的?结果一上手就栽了跟头。脚本跑着跑着就报错,说元素找不到。后来我才明白,定位不准,后面全是白搭

这一章,咱们先搞定五种最常用的定位方式。它们就像工具箱里的螺丝刀、扳手,你得知道什么时候用哪个。

3.1 ID定位:最快、最稳,没有之一

ID定位,说白了就是元素的身份证号。在HTML规范里,ID应该是唯一的。所以用ID定位,速度最快,也最不容易出错。

我个人习惯是:只要元素有ID,我优先用ID。为什么?因为简单、直接、不绕弯子。

核心要点:ID定位使用 find_element(By.ID, "id值") 方法。

来看个例子。假设页面上有个搜索框,HTML长这样:

<input type="text" id="search-input" placeholder="请输入关键词">

那咱们的Python代码就是:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com")

# ID定位搜索框
search_box = driver.find_element(By.ID, "search-input")
search_box.send_keys("自动化测试")

你看,三行代码搞定。我在项目中遇到过很多次,开发同学给元素加了动态ID,比如 id="user_12345",这种ID每次刷新都会变。嗯,这时候ID定位就不灵了。所以记住:静态ID用ID,动态ID别用ID

小技巧:在Chrome浏览器里,右键点击元素 → 检查,就能看到元素的ID。如果ID是纯数字或者带下划线,多半是动态生成的,要小心。

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

Name定位和ID定位很像,只不过用的是 name 属性。在表单提交的场景里,name属性几乎是标配。

你想想看,后端接收表单数据时,靠的就是name字段。所以登录框、注册页这些地方,name属性特别常见。

# Name定位
username = driver.find_element(By.NAME, "username")
password = driver.find_element(By.NAME, "password")

username.send_keys("admin")
password.send_keys("123456")

这里有个坑——name属性不要求唯一。同一个页面里,多个元素可能有相同的name。比如一组单选按钮,name都是 gender。这时候用 find_element 只会找到第一个,想找全部得用 find_elements

注意:如果页面里有多个同名name元素,find_element 返回第一个,find_elements 返回列表。我曾经因为没注意这个,脚本定位到了错误的元素,排查了半天才发现。

3.3 Class Name定位:样式即定位

Class Name定位,用的是元素的CSS类名。说实话,这个定位方式我用的频率没那么高,因为一个元素往往有多个class,而且class经常被用来控制样式,变化比较频繁。

但有些场景下,它特别好用。比如一组商品卡片,每个卡片都有 class="product-item",你想遍历所有商品,用Class Name定位就很方便。

# Class Name定位
products = driver.find_elements(By.CLASS_NAME, "product-item")
for product in products:
    print(product.text)

我记得有一次做电商项目,页面上的商品列表就是用class来区分的。我用 find_elements 一次性拿到了所有商品,然后逐个点击查看详情。嗯,效率确实高。

不过要提醒你:class name如果有空格,说明是多个class的组合。比如 class="btn btn-primary",你不能直接用 "btn btn-primary" 去定位,得用CSS选择器或者只用其中一个class。

避坑指南:Class Name定位只接受单个class名。如果元素有多个class,比如 class="a b c",用 By.CLASS_NAME, "a" 是可以的,但用 By.CLASS_NAME, "a b" 会报错。

3.4 Tag Name定位:最通用的“笨办法”

Tag Name定位,就是通过HTML标签名来找元素。比如 divspanainput 这些。

说实话,这个定位方式我平时用得最少。为什么?因为太宽泛了。一个页面上可能有几十个 div,你定位到哪个?

但它也不是一无是处。比如你想统计页面上有多少个链接,或者获取所有输入框,用Tag Name就很快。

# Tag Name定位
all_links = driver.find_elements(By.TAG_NAME, "a")
print(f"页面上共有 {len(all_links)} 个链接")

all_inputs = driver.find_elements(By.TAG_NAME, "input")
print(f"页面上共有 {len(all_inputs)} 个输入框")

我在做页面结构分析的时候,偶尔会用Tag Name来快速了解页面布局。比如检查是不是所有图片都有alt属性,就可以先拿到所有 img 标签,再逐个检查。

使用场景:Tag Name定位适合做批量操作或统计,不适合精确定位单个元素。如果你非要定位单个元素,建议配合索引使用,但说实话,那样代码可读性很差。

3.5 Link Text定位:专治各种超链接

Link Text定位,顾名思义,就是通过链接的文本内容来定位 <a> 标签。这个定位方式有两个变种:Link Text(精确匹配)和 Partial Link Text(部分匹配)。

我个人觉得,这个定位方式在测试导航菜单、面包屑导航、页脚链接时特别好用。因为链接文本通常是人眼可读的,写出来的代码也很直观。

# Link Text定位(精确匹配)
about_link = driver.find_element(By.LINK_TEXT, "关于我们")
about_link.click()

# Partial Link Text定位(部分匹配)
contact_link = driver.find_element(By.PARTIAL_LINK_TEXT, "联系")
contact_link.click()

这里有个细节要注意:Link Text定位只对 <a> 标签有效。如果你遇到的是 <button> 或者 <div> 模拟的链接,那就不能用这个方法了。

我曾经遇到过一个坑:页面上有两个链接,文本分别是「联系我们」和「联系客服」。我用 PARTIAL_LINK_TEXT 定位「联系」,结果找到了第一个。后来我改成精确匹配,才解决了问题。所以,能用精确匹配就别用部分匹配,除非你确定文本是唯一的。

注意:链接文本里的空格、换行、特殊字符都会影响匹配结果。比如「关于我们」和「关于 我们」就是两个不同的文本。建议先复制页面上的原文,再粘贴到代码里。

3.6 五种定位方式对比总结

好了,五种定位方式都讲完了。咱们来做个对比,方便你以后选择:

定位方式 依据属性 唯一性 速度 推荐场景
ID定位 id 通常唯一 最快 有静态ID的元素,优先选择
Name定位 name 可能不唯一 表单元素、输入框
Class Name定位 class 不唯一 中等 批量获取同类元素
Tag Name定位 标签名 不唯一 中等 统计、批量操作
Link Text定位 链接文本 通常唯一 超链接、导航菜单

最后说一句:没有最好的定位方式,只有最合适的。实际项目中,我经常是几种定位方式混着用。比如先用ID定位到某个容器,再用Class Name定位容器里的子元素。这种组合拳,往往比单一方式更稳。

下一章,咱们接着聊CSS选择器和XPath定位。这两种方式更灵活,但也更复杂。准备好了吗?