一. 元素的定位
find_element
web⾃动化测试的操作核⼼是能够找到⻚⾯对应的元素,然后才能对元素进⾏具体的操作。
常⻅的元素定位⽅式⾮常多。见元素定位方式(Selenium 支持)
定位方式 说明 示例 By.ID
根据元素的 id
属性,推荐使用driver.find_element(By.ID, "kw")
By.CLASS_NAME
根据 class
属性定位,适用于唯一类名driver.find_element(By.CLASS_NAME, "btn")
By.TAG_NAME
根据 HTML 标签名定位 driver.find_element(By.TAG_NAME, "input")
By.NAME
根据 name
属性定位driver.find_element(By.NAME, "wd")
By.CSS_SELECTOR
使用 CSS 语法进行组合定位,灵活强大 driver.find_element(By.CSS_SELECTOR, "#kw")
By.XPATH
使用 XPath 路径定位,适用于结构复杂的节点 driver.find_element(By.XPATH, "//input[@id='kw']")
1.cssSelector
使用 CSS 语法快速、精确选中页面中元素。
类型 | 示例 | 说明 |
---|---|---|
ID选择器 | #kw |
选中 id 为 kw 的元素 |
类名选择器 | .s_ipt |
选中 class 为 s_ipt 的元素 |
属性选择器 | input[name='wd'] |
选中具有特定属性的标签 |
子代选择器 | #s-hotsearch-wrapper > div |
热搜区域中直接子元素定位 |
组合选择器 | div > input.s_ipt#kw |
标签、类、id、属性组合定位 |
功能 | CSS Selector |
---|---|
搜索输入框 | #kw |
百度一下按钮 | #su |
热搜区域 | #s-hotsearch-wrapper > div |
选项名称 功能说明 Copy element 复制整个 HTML 元素(包括标签和内容),等同于右键 → "Copy → Element" Copy outerHTML 复制选中元素的 HTML 字符串(不含父级,仅自身) Copy selector 复制该元素的 CSS Selector 路径,适用于 By.CSS_SELECTOR
Copy JS path 复制通过 JS 脚本获取该元素的代码(如 document.querySelector(...)
)Copy styles 复制该元素当前计算出的所有 CSS 样式(computed style) Copy XPath 复制相对 XPath 路径(简短),用于 By.XPATH
Copy full XPath 复制绝对 XPath 路径(从根目录 html 开始的完整路径) Copy element:
<input type="submit" value="百度一下" id="su" class="btn self-btn bg s_btn">
Copy selector:
#su
两种定位方法By.ID By.CSS_SELECTOR
driver.find_element(By.CSS_SELECTOR, "#su").click()
driver.find_element(By.ID, "su").click()
eg.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import time
# 启动浏览器
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
# 打开百度首页
driver.get("https://www.baidu.com")
# 输入搜索内容(通过 CSS Selector 定位)
driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("迪丽热巴")
# 点击百度一下按钮
driver.find_element(By.CSS_SELECTOR, "#su").click()
# 等待搜索结果加载
time.sleep(2)
# 打印页面标题
print("当前页面标题:", driver.title)
# 关闭浏览器
driver.quit()
2.xpath
XPath 是一种路径语法,支持根据标签结构、属性、文本内容进行定位,功能更强但语法复杂。
功能 XPath 表达式 说明 所有节点 //*
页面中所有节点(不推荐用于实际脚本) 指定节点 //ul
、//input
查找所有该标签类型的节点 子节点 //span/input
span 下的 input 父节点 //input/..
获取 input 的父节点 属性等于 //*[@id='kw']
定位 id 为 kw 的任意节点 属性包含 //*[contains(@class,'title')]
class 属性包含 title 按下标定位(从 1 开始) //div/ul/li[3]
获取第三个热搜标签 文本匹配 //a[text()='登录']
匹配超链接文本内容 文本模糊匹配 //span[contains(text(),'百度')]
文本包含“百度”的 span
element:<span class="title-content-title">女子服刑10年将出狱:父母已病逝</span>
Xpath://*[@id="hotsearch-content-wrapper"]/li[9]/a/span[2]
部分 解释说明 //*[@id="hotsearch-content-wrapper"]
定位整个热搜列表区域,通常是 <ul>
标签/li[9]
在该热搜列表区域下,选择第 9 个 <li>
(第9条热搜)/a
进入 <li>
标签下的<a>
(每条热搜是个超链接)/span[2]
取 <a>
标签中的第二个<span>
元素,通常是热搜的具体标题内容搜索框XPatch:
//*[@id="kw"]
百度一下按钮XPatch:
//*[@id="su"]
eg.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import time
# 启动浏览器
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
# 打开百度首页
driver.get("https://www.baidu.com")
# 输入搜索内容(通过 XPath 定位)
driver.find_element(By.XPATH, "//input[@id='kw']").send_keys("迪丽热巴")
# 点击百度一下按钮
driver.find_element(By.XPATH, "//input[@id='su']").click()
# 等待搜索结果加载
time.sleep(2)
# 打印页面标题
print("当前页面标题:", driver.title)
# 关闭浏览器
driver.quit()
input[@id='su']和*[@id='su']
浏览器在解析 XPath 时,如果明确了标签类型(如
input
就知道你要找的是按钮或输入元素),比起万能星号*
更快更准确。
二. 操作测试对象
获取到了⻚⾯的元素之后,接下来就是要对元素进⾏操作了。常⻅的操作有点击、提交、输⼊、清除、获取⽂本。
1.点击/提交对象 click()
#找到百度⼀下按钮并点击
driver.find_element(By.CSS_SELECTOR, "#su").click()
2. 模拟按键输⼊ send_keys("")
driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("迪丽热巴")
3.清除⽂本内容clear()
清除搜索框的内容重新输入
driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("迪丽热巴")
time.sleep(1)
driver.find_element(By.CSS_SELECTOR,"#kw").clear()
time.sleep(1)
driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("古⼒娜扎")
4.获取⽂本信息text
如果判断获取到的元素对应的⽂本是否符合预期呢?获取元素对应的⽂本并打印⼀下~~
获取⽂本信息.
text=driver.find_element(By.CSS_SELECTOR,
'#hotsearch-content-wrapper > li:nth-child(8) > a > span.title-content-title').text
print(text)
获取到文本信息后 用assert断言来判断是否一致
get_attribute("属性名称")
我想查看 百度一下 这四个字对不对怎么办?
可以通过 text 获取到“百度⼀下按钮”上的⽂字“百度⼀下”呢?
不行,因为这不是文本信息,而是元素的属性值。
想下面<>外的黑色字体才是文本信息。
获取属性值需要使⽤⽅法 get_attribute("属性名称") 返回key对应value值
5.获取当前⻚⾯标题 title
title = driver.title
6.获取当前⻚⾯URL current_url
url = driver.current_url
用来判断跳转的网页是否正确
三.窗⼝
当我们⼿⼯测试的时候,我们可以通过眼睛来判断当前的窗⼝是什么,但对于程序来说它是不知道当前最新的窗⼝应该是哪⼀个。
对于程序来说它怎么来识别每⼀个窗⼝呢?每个浏览器窗⼝都有⼀个唯⼀的属性句柄(handle)来表⽰,我们就可以通过句柄来切换
每一个浏览器窗口(或标签页)在 Selenium 中都有一个 唯一的 ID,叫做 句柄;
Selenium 使用这些句柄来识别你当前正在操作的是哪一个页面。
driver 本质是 WebDriver 对象实例
它是你与 浏览器之间通信的控制器,也是整个 Selenium 脚本的“操作入口”。
from selenium import webdriver driver = webdriver.Chrome()
这一行:
创建了一个 Chrome 浏览器驱动对象实例;
把它赋值给变量 driver;
后续所有的浏览器操作(打开页面、查找元素、点击、截图等)都是通过这个 driver 来执行的。
1.切换窗⼝
1.获取当前页面的句柄:current_window_handle
curWindow = driver.current_window_handle
意思是记录你当前打开的这个页面的 ID。
2.获取所有打开的窗口句柄:window_handles
allWindows = driver.window_handles
返回的是一个列表,包含所有窗口的句柄。
3.切换到新的标签页:switch_to.window(新标签页句柄)
因为我们只新开一个标签页 allWindows里面就两个标签页 通过遍历找新开的标签页
for window in allWindows: if window != curWindow: driver.switch_to.window(window)
一般只会打开两个标签页 不会打开更多
或者直接点击输入网址来进行标签页的切换
2.窗⼝设置⼤⼩
#窗⼝最⼤化 driver.maximize_window() #窗⼝最⼩化 driver.minimize_window() #窗⼝全屏 driver.fullscreen_window() #⼿动设置窗⼝⼤⼩ driver.set_window_size(1024,768)
一般在自动化的时候不关心窗口大小
3.屏幕截图 save_screenshot("文件路径+截屏图片名")
我们的⾃动化脚本⼀般部署在机器上⾃动的去运⾏,如果出现了报错,我们是不知道的,可以通过抓拍来记录当时的错误场景。
driver.save_screenshot('../images/image.png')
为了防止重名 我们一般在文件名中加上时间 并转为对应格式不能包含空格
记得加图片缀.png
filename = "autotest-"+datetime.datetime.now().strftime('%Y-%m-%d-%H%M%S')+'.png' driver.save_screenshot('../images/'+filename)
4.关闭窗⼝ close()
关闭当前标签页 即driver指向的标签页
想再操作其它标签页还需重新定义
driver.close() 注意:窗⼝关闭后driver要重新定义
打开并切换到新标签页 操作完关闭并回到旧标签页
# 打开一个新的标签页 driver.execute_script("window.open('https://www.baidu.com');") time.sleep(1) # 所有窗口 handles = driver.window_handles # 切换到新标签页 driver.switch_to.window(handles[-1]) # 执行操作... # 关闭当前(新)标签页,并切回原标签页 driver.close() driver.switch_to.window(handles[0])
driver.close()关闭标签页!=driver.quit()关闭浏览器
索引 含义 handles[0]
第一个标签页(最早打开的窗口) handles[-1]
最后一个标签页(最新打开的窗口)
四.弹窗
如果当前页面出现了弹窗(Alert、Confirm、Prompt),你必须先处理弹窗,否则你继续操作页面元素会抛出异常!
弹窗分为三种 1.警告弹窗 2.确认弹窗 3.提升弹窗
adriver.switch_to.alert 切换到弹窗
动作 对应代码 检测弹窗 driver.switch_to.alert
获取弹窗文字 alert.text
点击“确定” alert.accept()
点击“取消” alert.dismiss()
提示框输入内容 alert.send_keys("内容")
弹窗存在时再继续操作页面 必须先处理 alert 后再操作页面
警告弹窗 确认弹窗
警告弹窗 只有确认alert.accept()
确认弹窗 有确认和取消 alert.accpet() alert.dismiss()
from selenium import webdriver
alert = driver.switch_to.alert
# 确认(点击“确定”)
alert.accept()
# 取消(点击“取消”,适用于 confirm 弹窗)
# alert.dismiss()
提⽰弹窗
提示弹窗 还可以输入文本信息 alert.send_keys(" ")
alert = driver.switch_to.alert
# 向输入框发送内容
alert.send_keys("hello")
# 确认提交
alert.accept()
# 或取消
# alert.dismiss()
五.等待
通常代码执⾏的速度⽐⻚⾯渲染的速度要快,如果避免因为渲染过慢出现的⾃动化误报的问题呢?可以使⽤selenium中提供的三种等待⽅法:
1 强制等待time.sleep()
强制等待__秒
优点:使⽤简单,调试的时候⽐较有效
缺点:影响运⾏效率,浪费⼤量的时间
2.隐式等待 implicitly_wait()
隐式等待是⼀种智能等待,他可以规定在查找元素时,在指定时间内不断查找元素。如果找到则代码继续执⾏,直到超时没找到元素才会报错。
implicitly_wait()最多等待__秒 在这期间会一直查找 找到就继续执行不会继续等待 没找到就会报错
#隐式等待5秒
driver.implicitly_wait(5)
隐式等待作⽤域是整个脚本的所有元素。即只要driver对象没有被释放掉( driver.quit() ),隐式等待就⼀直⽣效。
从定义driver.implicitly_wait()开始 每次查找元素都会进行隐式等待
优点:智能等待,作⽤于全局
3.显示等待 WebDriverWait(driver,_秒_) + wait.until(expected_conditions._函数_)
expected_conditions 导入进行取别名 as EC
和隐式等待不同的是,显示等待 可以只针对特定的元素进行等待。
隐式等待只能等待元素是否出现,显示等待能有更多的操作
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC wait = WebDriverWait(driver, 10) # 最多等10秒 # 等待元素“可见”并“可交互” wait.until(EC.element_to_be_clickable((By.ID, "kw"))).send_keys("古力娜扎")
因为element_to_be_clickable()函数只要一个参数 用()括起来传
from selenium.webdriver.support import expected_conditions as EC 取别名
✅ 灵活等待:你可以等它“出现”、“可见”、“可点击”、“不可见”或“文本为某值”等。
✅ 精准控制逻辑,适合复杂页面和动态 JS 内容。
方法名 描述 presence_of_element_located
元素出现在 DOM 中,但不一定可见 visibility_of_element_located
元素在页面上可见 element_to_be_clickable
元素可见 + 可点击 invisibility_of_element
元素不可见(可用于等待加载动画消失) title_is
,title_contains
等待标题为某个值 alert_is_present
等待弹窗出现
隐式等待和显示等待不要一起用
容易导致总等待时间不可预测,特别是在执行 .until(...) 时内部调用 find_element 会再受隐式等待控制。
但强制等待可以和其它一起使用
项目 隐式等待(Implicit Wait) 显式等待(Explicit Wait) 作用方式 为所有 find_element()
设置一个最大等待时间为某个特定元素/条件设置等待策略 作用范围 全局(只要 driver
不被释放)局部(只影响当前这次等待) 用法简单程度 简单(设置一次就生效) 稍复杂(要配合 WebDriverWait + EC
使用)精准控制 ❌ 不能控制等待什么条件,只能等“元素是否出现” ✅ 可以等待元素出现、可点击、消失、弹窗、文本等 是否推荐长期用 ❌ 不推荐依赖 ✅ 推荐,更灵活、安全、可控
六. 浏览器导航
1.打开⽹站 get("网址")
driver.get("https://www.baidu.com/")
2.浏览器的前进forword()、后退back()、刷新refresh()
driver.back() driver.forward() driver.refresh()
七.⽂件上传send_keys()
当你点击
<input type="file">
时,浏览器会弹出一个系统文件选择对话框(非 HTML DOM 元素),而:Selenium 无法操作这种系统弹窗(不是网页元素)
,但我们可以通过.send_keys("文件路径")
直接把路径赋值到这个控件上,实现“上传”。
# 找到 input[type=file] 元素
file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
# 模拟上传:指定文件绝对路径
file_input.send_keys("D:\\file\\test.txt")
八.浏览器参数设置
1.设置⽆头模式 options.add_argument("-headless")
无头模式 不显示页面 在后台运行
options = webdriver.ChromeOptions() options.add_argument("-headless") driver=webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()) ,options=options)
2.页面加载策略 options.page_load_strategy='加载方式'
策略值 含义 normal
默认行为,等待所有资源加载完才执行脚本,包括图片、CSS、JS等 eager
只等DOM 内容加载完成(文字 按钮),但不等图片等其他静态资源(更快,推荐) none
只请求了 URL,不等待页面结构(几乎不实用,风险高) options = webdriver.ChromeOptions() options.page_load_strategy = 'eager' # 或 'none', 'normal'
使用场景 推荐配置 后台批量运行 --headless + eager
图像元素需截图 不建议无头,或加 --window-size
页面超大、加载慢 eager
提升速度性能测试 none
(非常小众)