2、Selenium基础入门:WebDriver核心API、元素定位八大方法、浏览器基本操作

好,咱们正式开始动手了。

上一章我们把环境搭好了,浏览器能跑起来了。但说实话,那只是开胃菜。真正的自动化,核心就两件事:找到元素操作元素

这一章,我就带你把这套基本功打扎实。你想想看,如果连元素都定位不到,后面的点击、输入、截图全是空谈。我在项目里见过太多人,代码写了一大堆,最后卡在「找不到元素」这个坎上,一卡就是半天。

2.1 WebDriver核心API:你手里的遥控器

WebDriver 是什么?说白了,它就是你和浏览器之间的「遥控器」。你通过它发号施令,浏览器乖乖执行。

我个人习惯,拿到 WebDriver 对象后,第一件事就是设置隐式等待。为什么?因为网页加载有延迟,你不等它,它就不等你。我曾经在刚入行时,因为没加等待,脚本跑得飞快,结果元素还没渲染出来就报错了。嗯,从那以后,我养成了这个习惯。

核心API速览

  • driver.get(url) — 打开指定网址
  • driver.quit() — 关闭整个浏览器
  • driver.close() — 关闭当前标签页
  • driver.current_url — 获取当前页面URL
  • driver.title — 获取页面标题
  • driver.page_source — 获取页面源码
  • driver.back() / driver.forward() — 后退/前进
  • driver.refresh() — 刷新页面
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
print("当前标题:", driver.title)
print("当前URL:", driver.current_url)
driver.quit()

你看,代码就这么几行。但别小看它,这是所有自动化脚本的骨架。

2.2 元素定位八大方法:找东西的十八般武艺

这是本章的重头戏。Selenium 提供了8种定位元素的方法,我按使用频率给你排个序。

定位方法 By 类型 示例 我的推荐指数
ID 定位 By.ID find_element(By.ID, "username") ⭐⭐⭐⭐⭐
Name 定位 By.NAME find_element(By.NAME, "password") ⭐⭐⭐⭐
Class Name 定位 By.CLASS_NAME find_element(By.CLASS_NAME, "btn") ⭐⭐⭐
Tag Name 定位 By.TAG_NAME find_element(By.TAG_NAME, "input") ⭐⭐
Link Text 定位 By.LINK_TEXT find_element(By.LINK_TEXT, "登录") ⭐⭐⭐⭐
Partial Link Text By.PARTIAL_LINK_TEXT find_element(By.PARTIAL_LINK_TEXT, "登") ⭐⭐⭐
CSS 选择器 By.CSS_SELECTOR find_element(By.CSS_SELECTOR, "#id .class") ⭐⭐⭐⭐⭐
XPath 定位 By.XPATH find_element(By.XPATH, "//input[@id='kw']") ⭐⭐⭐⭐⭐

我的个人经验:能用 ID 就用 ID,它是唯一且最快的。如果页面没有 ID,优先考虑 CSS 选择器。XPath 虽然强大,但性能稍差,而且写长了容易出问题。我曾经维护过一个项目,里面全是长长的 XPath,每次页面改版都要改半天,后来我全部重构成了 CSS 选择器,清爽多了。

2.2.1 ID 定位 — 最快最稳

search_box = driver.find_element(By.ID, "kw")
search_box.send_keys("Selenium")

为什么快?因为 ID 在 HTML 里是唯一的。浏览器找它就像按门牌号找人,一步到位。

2.2.2 Name 定位 — 表单常用

password = driver.find_element(By.NAME, "password")
password.send_keys("123456")

很多表单元素都有 name 属性,尤其是登录注册页面。但注意,name 不保证唯一,如果有多个同名的,find_element 只返回第一个。

2.2.3 Class Name 定位 — 小心重复

button = driver.find_element(By.CLASS_NAME, "btn-primary")
button.click()

class 是样式类,同一个 class 可能对应几十个元素。如果你只想点其中一个,最好配合其他属性一起定位。

2.2.4 Tag Name 定位 — 最不推荐

all_inputs = driver.find_elements(By.TAG_NAME, "input")

这个我基本不用。你想啊,一个页面可能有几十个 <input>,你定位到哪个?除非你要批量操作,否则别用。

2.2.5 Link Text 和 Partial Link Text — 专治超链接

login_link = driver.find_element(By.LINK_TEXT, "立即登录")
login_link.click()

# 或者只匹配部分文本
login_link = driver.find_element(By.PARTIAL_LINK_TEXT, "登录")

这两个方法只对 <a> 标签有效。我个人更推荐用完整的 Link Text,因为更精确。Partial 容易匹配到多个,比如「登录」和「注册登录」可能同时被匹配到。

2.2.6 CSS 选择器 — 我的最爱

# 通过 ID 选择
driver.find_element(By.CSS_SELECTOR, "#kw")

# 通过 class 选择
driver.find_element(By.CSS_SELECTOR, ".btn-primary")

# 通过属性选择
driver.find_element(By.CSS_SELECTOR, "input[name='username']")

# 层级选择
driver.find_element(By.CSS_SELECTOR, "div.form-group > input")

CSS 选择器语法简洁,性能也好。我在项目中 80% 的定位都用它。你想想看,一行代码就能搞定复杂的层级关系,多爽。

2.2.7 XPath 定位 — 万能但啰嗦

# 绝对路径(不推荐)
driver.find_element(By.XPATH, "/html/body/div[1]/div[2]/input")

# 相对路径(推荐)
driver.find_element(By.XPATH, "//input[@id='kw']")

# 包含文本
driver.find_element(By.XPATH, "//button[contains(text(), '提交')]")

# 多条件组合
driver.find_element(By.XPATH, "//input[@type='text' and @name='username']")

避坑指南:我曾经接手过一个项目,里面全是类似 /html/body/div[1]/div[2]/div[3]/div[4]/input 这样的绝对路径 XPath。结果前端加了一个 div,整个脚本全废了。记住:永远不要用绝对路径。用相对路径,结合属性或文本,才是正道。

2.3 浏览器基本操作:让浏览器动起来

定位到元素之后,接下来就是操作了。浏览器操作其实就那么几样,我帮你捋一捋。

2.3.1 窗口操作

# 最大化窗口
driver.maximize_window()

# 设置窗口大小
driver.set_window_size(1024, 768)

# 获取窗口大小
size = driver.get_window_size()
print("窗口宽:", size['width'], "高:", size['height'])

# 滚动到页面底部
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")

为什么要最大化?因为有些元素在窗口太小的时候会被隐藏,你定位不到。我习惯在脚本一开始就 maximize_window(),省得后面出幺蛾子。

2.3.2 页面导航

# 打开页面
driver.get("https://www.baidu.com")

# 后退
driver.back()

# 前进
driver.forward()

# 刷新
driver.refresh()

这几个方法在测试多页面跳转时特别有用。比如你提交一个表单后,页面跳转了,你想验证能不能回到上一页,就可以用 back()forward() 来模拟用户操作。

2.3.3 元素基本操作

# 点击
element.click()

# 输入文本
element.send_keys("Hello World")

# 清空输入框
element.clear()

# 获取文本
text = element.text

# 获取属性值
attr = element.get_attribute("href")

# 判断是否可见
is_visible = element.is_displayed()

# 判断是否可用
is_enabled = element.is_enabled()

一个小技巧:在输入文本之前,最好先 clear() 一下。为什么?因为有些输入框默认有 placeholder 文本,或者之前已经被填过内容。不清空的话,新输入的内容会追加在后面。我曾经因为这个 bug 排查了半天,最后发现是没清空输入框。

2.4 实战:一个完整的登录脚本

光说不练假把式。咱们来写一个完整的登录自动化脚本,把今天学的知识串起来。

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

# 1. 启动浏览器
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://example.com/login")

# 2. 定位并输入用户名
username = driver.find_element(By.ID, "username")
username.clear()
username.send_keys("admin")

# 3. 定位并输入密码
password = driver.find_element(By.NAME, "password")
password.clear()
password.send_keys("123456")

# 4. 点击登录按钮
login_btn = driver.find_element(By.CSS_SELECTOR, "button.btn-login")
login_btn.click()

# 5. 等待页面跳转
time.sleep(2)

# 6. 验证是否登录成功
welcome_text = driver.find_element(By.CLASS_NAME, "welcome").text
if "欢迎" in welcome_text:
    print("登录成功!")
else:
    print("登录失败,请检查")

# 7. 关闭浏览器
driver.quit()

你看,整个流程就是:打开页面 → 找元素 → 操作元素 → 验证结果 → 关闭。所有自动化脚本都逃不出这个框架。

2.5 本章小结

这一章我们学了三个核心内容:

  • WebDriver 核心API:get、quit、close、back、forward 这些基本操作
  • 八大定位方法:ID、Name、Class、Tag、Link Text、Partial Link Text、CSS、XPath
  • 浏览器基本操作:窗口管理、页面导航、元素交互

说实话,这些就是 Selenium 的「内功心法」。你把这些练熟了,后面学什么框架、什么设计模式,都只是招式变化而已。

下一章,咱们聊聊「等待机制」。为什么有时候元素明明在页面上,脚本就是找不到?嗯,这里面的坑,我踩过不少,到时候一一讲给你听。