2、Selenium基础入门:WebDriver核心API、元素定位八大方法、浏览器基本操作
好,咱们正式开始动手了。
上一章我们把环境搭好了,浏览器能跑起来了。但说实话,那只是开胃菜。真正的自动化,核心就两件事:找到元素,操作元素。
这一章,我就带你把这套基本功打扎实。你想想看,如果连元素都定位不到,后面的点击、输入、截图全是空谈。我在项目里见过太多人,代码写了一大堆,最后卡在「找不到元素」这个坎上,一卡就是半天。
2.1 WebDriver核心API:你手里的遥控器
WebDriver 是什么?说白了,它就是你和浏览器之间的「遥控器」。你通过它发号施令,浏览器乖乖执行。
我个人习惯,拿到 WebDriver 对象后,第一件事就是设置隐式等待。为什么?因为网页加载有延迟,你不等它,它就不等你。我曾经在刚入行时,因为没加等待,脚本跑得飞快,结果元素还没渲染出来就报错了。嗯,从那以后,我养成了这个习惯。
核心API速览
driver.get(url)— 打开指定网址driver.quit()— 关闭整个浏览器driver.close()— 关闭当前标签页driver.current_url— 获取当前页面URLdriver.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 的「内功心法」。你把这些练熟了,后面学什么框架、什么设计模式,都只是招式变化而已。
下一章,咱们聊聊「等待机制」。为什么有时候元素明明在页面上,脚本就是找不到?嗯,这里面的坑,我踩过不少,到时候一一讲给你听。