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选择器——这两个才是真正的杀手锏。

记住一句话:定位方式没有最好的,只有最合适的。多练、多试,你自然就知道什么时候该用哪个了。