吊打 Web 自动化测试!一篇吃透 Selenium 元素定位 + 核心函数,新手直接上手
目录
一、前言
通过概念篇,你一定理解了web自动化示例怎么就能按照你的代码执行自动化,但是又可能又会带有新的好奇,一个web网页界面这么多元素,它是怎么找到的,还有好几个如findElement() 等方法中,怎么有些出现了奇怪的字符串,它又是用来干什么的,它们作业又是什么?
别慌,这些东西只是涉及到元素的定位和⾃动化测试常⽤函数内容,今天这篇文章就来让你来更深刻的掌握自动化测试,保证你看完后,直接可以上手项目测试
二、元素的定位
web⾃动化测试的操作核⼼是能够找到⻚⾯对应的元素,然后才能对元素进⾏具体的操作。
常⻅的元素定位⽅式⾮常多,如id,classname,tagname,xpath,cssSelector常⽤的主要由cssSelector和xpath
1. xpath
XML路径语⾔,不仅可以在XML⽂件中查找信息,还可以在HTML中选取节点。
xpath使⽤路径表达式来选择xml⽂档中的节点
1.2. 找到“xpath 路径”
通过边用边学的方法来学如何正确使用xpath
目的: 找到输入框

By.xpath("xxx"):用 “xpath 路径” 定位输入框
找到 “xpath 路径”
1.打开浏览器并进入百度一下首页
2.按键盘F12,打开开发者工具
3.点击左上角的 ’Select an element in the page to inspect it’ ,将鼠标移动到搜索框上后点击鼠标
点击后的蓝色框就是要定位的元素位置

4.将鼠标移动到蓝色框后点击鼠标右键点击Copy后在点击Copy XPath
此刻复制的内容,就是 “xpath 路径”

1.3 xpath语法
//*:获取HTML⻚⾯所有的节点
2. //[指定节点]:获取HTML⻚⾯指定的节点
//ul :获取HTML⻚⾯所有的ul节点
/:获取⼀个节点中的直接⼦节点
//*[@id=“chat-input-main”]/div[4]/div[1]/div[1]
[@...]:实现节点属性的匹配
//*[@id=‘kw’]匹配HTML⻚⾯中id属性为kw的节点
注意:元素的定位⽅法必须唯⼀
2. cssSelector
选择器的功能:选中⻚⾯中指定的标签元素
选择器的种类分为基础选择器和复合选择器,常⻅的元素定位⽅式可以通过id选择器和⼦类选择器来进⾏定位。
2.1 使用选择器定位元素
cssSelector的元素定位方法和找到“xpath 路径”一样,只不过最后点击的是Copy selector

目的: 定位百度搜索框By.cssSelector("xxx"):用选择器定位输入框
三、⾃动化测试常⽤函数
3.1 操作测试对象
获取到了⻚⾯的元素之后,接下来就是要对元素进⾏操作了。常⻅的操作有点击、提交、输⼊、清除、获取⽂本
click()
作用: 为点击/提交对象
代码演示
目的: 找到百度⼀下按钮并点击
driver.findElement(By.xpath("//*[@id=\"chat-submit-button\"]")).click();通过xpath路径定位到元素后,通过click()点击,相当于,找到百度⼀下按钮并点击
特殊元素
页面上的绝大数的元素都可以点击,只有部分页面隐藏的,不可见的标签元素无法点击
对不可交互的元素执行,会报错

sendKeys(“”)
作用: 模拟按键输⼊
代码演示
目的: 找到搜索框并输入“胡歌”
driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("胡歌");连续的sendKeys具有追加效果
//追加效果 driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("胡歌"); driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("邓超");
clear()
作用: 清除⽂本内容
输⼊⽂本后⼜想换⼀个新的关键词,这⾥就需要⽤到clear()
代码演示
目的: 找到搜索框并输入“胡歌”后清理输入框中的“胡歌”
driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("胡歌"); driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).clear();getText()
作用: 获取⽂本信息
通过getText我们可以判断获取到的元素是否符合预期
目的: 找到搜索框并输入“胡歌”后获取对应元素的文本内容
driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("胡歌");String text =driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).getText();System.out.println("获取到的文本为:"+text);注意:getText()只可以获取信息⽂本,不可以获取属性值,获取属性值需要使⽤⽅法getAttribute("属性名称")

getTitle()
作用: 获取当前⻚⾯标题
WebDriver driver =newChromeDriver(options); driver.get("https://www.baidu.com"); driver.getTitle();// 获取当前页面标题:“百度一下,你就知道”getCurrentUrl()
作用: 获取当前⻚⾯URL
WebDriver driver =newChromeDriver(options); driver.get("https://www.baidu.com"); driver.getCurrentUrl();//获取当前⻚⾯URL:https://www.baidu.com/扩展窗口问题
当我们执行进入百度页面后点击图片的自动化操作效果,用 getCurrentUrl() 获取当前⻚⾯URL,按照我们执行的思路,想必获取的肯定是图片页面的URL吧
//进入百度页面后点击图片页面 driver.get("https://www.baidu.com");String titleBefore=driver.getTitle();String urlBefore=driver.getCurrentUrl(); driver.findElement(By.xpath("//*[@id=\"s-top-left\"]/a[6]")).click();String titleAfter=driver.getTitle(); driver.getCurrentUrl();String urlAfter=driver.getCurrentUrl();System.out.println("跳转之前的标题:"+titleBefore);System.out.println(urlBefore);System.out.println("跳转之后的标题:"+titleAfter);System.out.println(urlAfter);
自动化执行成功,说明已经按照代码的执行,进入百度页面后点击图片页面进入图片页面,但是通过打印的日志得知并没有获取跳转后图片页面的url和标题,这就奇怪了明明代码是执行成功的.
页面句柄
其实核心原因是新标签页打开后, driver 实例仍停留在原标签页,所以获取的还是原页面的信息,每个标签页都会有自己页面的句柄,我们可以通过getWindowHandle()打印标签页句来验证driver 实例是否仍停留在原标签页
getWindowHandle()获取当前句柄
getWindowHandles()获取所有页面的句柄,用set存储所有句柄
//进入百度页面后点击图片页面 driver.get("https://www.baidu.com");System.out.println("当前页面句柄:"+driver.getWindowHandle());String titleBefore=driver.getTitle();String urlBrfore=driver.getCurrentUrl(); driver.findElement(By.xpath("//*[@id=\"s-top-left\"]/a[6]")).click();System.out.println("当前页面句柄:"+driver.getWindowHandle());String titleAfter=driver.getTitle(); driver.getCurrentUrl();String urlAfter=driver.getCurrentUrl();System.out.println("跳转之前的标题:"+titleBefore);System.out.println(urlBrfore);System.out.println("跳转之后的标题:"+titleAfter);System.out.println(urlAfter);
通过验证 driver 实例仍停留在原标签页,所以如果要获得跳转页面的url之类的,直接用 getCurrentUrl 是行不通的,这时我们就要使用页面切换,使得driver 实例停留在跳转页面标签页
页面切换
driver.switchTo().window() 表示将driver实例停留在输入的句柄中,也就是页面切换
切换页面示例演示
//进入百度页面后点击图片页面 driver.get("https://www.baidu.com");String curWindow=driver.getWindowHandle();System.out.println("当前页面句柄:"+curWindow);String titleBefore=driver.getTitle();String urlBrfore=driver.getCurrentUrl();System.out.println("跳转之前的标题:"+titleBefore);System.out.println(urlBrfore); driver.findElement(By.xpath("//*[@id=\"s-top-left\"]/a[6]")).click();System.out.println("打印当前页面所有句柄:");Set<String> allWindow = driver.getWindowHandles();for(String window:allWindow){System.out.println(window);}//切换页面for(String window : allWindow){if(!window.equals(curWindow)){ driver.switchTo().window(window);}}String titleAfter=driver.getTitle();String urlAfter=driver.getCurrentUrl();System.out.println("跳转之后的标题:"+titleAfter);System.out.println(urlAfter);//5、关闭浏览器 driver.quit();
根据运行结果,自动化按照我们想执行的思路,成功获取跳转后的url
3.2 窗⼝
窗⼝设置⼤⼩
//窗⼝最⼤化 driver.manage().window().maximize();//窗⼝最⼩化 driver.manage().window().minimize();//全屏窗⼝ driver.manage().window().fullscreen();//⼿动设置窗⼝⼤⼩ driver.manage().window().setSize(newDimension(1024,768));屏幕截图
我们的⾃动化脚本⼀般部署在机器上⾃动的去运⾏,如果出现了报错,我们是不知道的,可以通过抓拍来记录当时的错误场景
屏幕截图⽅法需要额外导⼊包:
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency>//捕获截图并生成临时文件File file =((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);//将临时截图文件复制到指定路径FileUtils.copyFile(file,newFile(filename));代码演示:捕获百度首页截图
//驱动程序管理的自动化WebDriverManager.chromedriver().setup();ChromeOptions options =newChromeOptions();//允许访问所有链接 options.addArguments("--remote-allow-origins=*");//1、打开浏览器WebDriver driver =newChromeDriver(options); driver.get("https://www.baidu.com");File file=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(file,newFile("test.png"));//5、关闭浏览器 driver.quit();运行结果:

避免截图覆盖问题
直接将临时截图文件复制会因为图片名字一样而造成截图覆盖问题,避免生成屏幕截图的图片文件因为重名而被覆盖,要求每次生成的屏幕截图图片文件名称是唯一的,这时就可以用时间戳来命名文件
2025-12-26 2025-12-27
хxхxхххх.png хxXXXXxX.png
xxxxxxxX.png xxXxxXXx.png
年月日时分秒亳秒
2025-12-26-18484950.png 2025-12-27-18184955.png
2025-12-26-18484955.png
WebDriverManager.chromedriver().setup();ChromeOptions options =newChromeOptions(); options.addArguments("--remote-allow-origins=*");WebDriver driver =newChromeDriver(options);//用时间搓来命名文件名SimpleDateFormat sim1 =newSimpleDateFormat("yyyy-MM-dd");SimpleDateFormat sim2 =newSimpleDateFormat("HH-mm-ss-SS");String dirTime = sim1.format(System.currentTimeMillis());String fileTime = sim2.format(System.currentTimeMillis());// 图片文件名: ./src/test/images/2025-12-26/18-56-57-50.pngString filename ="./src/test/images/"+ dirTime +"/"+ fileTime +".png";File srcfile =((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(srcfile,newFile(filename)); driver.quit();运行结果:

关闭窗⼝
driver.close()为关闭当前被 driver 聚焦的标签页 / 窗口,注意不是关闭整个浏览器,如果只有一个窗口的情况下才会关闭整个浏览器
3.3 等待
通常代码执⾏的速度⽐⻚⾯渲染的速度要快,如果避免因为渲染过慢出现的⾃动化误报的问题呢?可以使⽤selenium中提供的三种等待⽅法:
1. Thread.sleep()
Thread.sleep() 这个大家应该很熟悉了就是将阻塞当前线程,线程阻塞了,自然可以等待的⻚⾯渲染
优点:使⽤简单,调试的时候⽐较有效
缺点:影响运⾏效率,如果有上千个页面,那浪费⼤量的时间
2. 隐式等待
隐式等待是⼀种智能等待,他可以规定在查找元素时,在指定时间内不断查找元素。如果找到则代码继续执⾏,直到超时没找到元素才会报错
优点:智能等待,作⽤于全局
使用implicitlyWait(),参数为Duration类中提供的毫秒、秒、分钟等⽅法

示例:
//隐式等待2000毫秒 driver.manage().timeouts().implicitlyWait(Duration.ofMillis(2000));//隐式等待2秒 driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));隐式等待作⽤域是整个脚本的所有元素。即只要driver对象没有被释放掉(driver.quit()),隐式等待就⼀直⽣效
3. 显⽰等待
显式等待是指针对特定的元素或条件,设置一个最长等待时间,在这个时间范围内,程序会周期性地检查条件是否满足。一旦条件满足,就立即执行后续操作;如果超过最长等待时间条件仍不满足,则抛出超时异常

它和隐式等待(Implicit Wait) 最大的区别是:显式等待是针对性的、更灵活的,只作用于指定的元素 / 条件,而隐式等待是全局的、对所有元素生效
优点:显⽰等待是智能等待,可以⾃定义显⽰等待的条件,操作灵活
缺点:写法复杂,作用于单个 / 特定元素的单次操作,只针对你指定的某个元素、某个条件生效,是 “按需触发” 的局部等待
显⽰等待的格式:
newWebDriverWait(driver,Duration.ofSeconds(5)).until()Duration.ofSeconds()和隐式等待一样:参数为Duration类中提供的毫秒、秒、分钟等⽅法

until 参数:涉及到selenium.support.ui.ExpectedConditions包下的ExpectedConditions类
ExpectedConditions预定义⽅法的⼀些⽰例
- elementToBeClickable(By locator): ⽤于检查元素的期望是可⻅的并已启⽤,以便您可以单击它
- textToBe(Bylocator,String str): 检查元素
- presenceOfElementLocated(Bylocator): 检查⻚⾯的DOM上是否存在元素
- urlToBe(java.lang.String url): 检查当前⻚⾯的URL是⼀个特定的URL
返回值:boolean
示例:
WebDriverManager.chromedriver().setup();ChromeOptions options =newChromeOptions(); options.addArguments("--remote-allow-origins=*");WebDriver driver =newChromeDriver(options); driver.get("https://www.baidu.com"); driver.findElement(By.xpath("//*[@id=\\\"chat-textarea\\\"]")).sendKeys("胡歌");WebDriverWait wait =newWebDriverWait(driver,Duration.ofMillis(1000)); wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\\\"chat-submit-button\\\"]"))); driver.quit();注意:不要混合隐式和显式等待,可能会导致不可预测的等待时间

3.4 浏览器导航
打开⽹站
// 更⻓的⽅法 driver.navigate().to("https://www.baidu.com");// 简洁的⽅法 driver.get("https://www.baidu.com");浏览器的前进、后退、刷新
//后退 driver.navigate().back();//前进 driver.navigate().forward();//刷新 driver.navigate().refresh();3.5 弹窗
之前的大部分操作都是建立在页面元素上,但是弹窗是在⻚⾯是找不到任何元素的,这种情况怎么处理?使⽤selenium提供的Alert接⼝

警告弹窗+确认弹窗

Alert alert = driver.switchTo.alert();//确认 alert.accept()//取消 alert.dismiss()如果只有一个按钮,使用accept()和dismiss()是一样的效果
提⽰弹窗

Alert alert = driver.switchTo.alert(); alert.sendKeys("hello selenium"); alert.accept(); alert.dismiss();3.5 ⽂件上传
点击文件上传按钮后会弹出系统自带的文件选择窗口,这个窗口不属于 Web 页面元素,所以 Selenium 识别不了也操作不了。
但咱们可以用 sendkeys 给上传输入框直接传入文件的路径,这样不用手动选文件,也能达到上传的目的
WebDriverManager.chromedriver().setup();ChromeOptions options =newChromeOptions(); options.addArguments("--remote-allow-origins=*");WebDriver driver =newChromeDriver(options); driver.get("file:///C:/Users/29113/AppData/Local/Temp/95a0f294-22c3-4e7c-b972-a575719f27cb_selenium-html.rar.selenium-html.rar/selenium-html/upload.html");//文件上传WebElement upload = driver.findElement(By.xpath("/html/body/div/div/input")); upload.sendKeys("C:\\Users\\29113\\AppData\\Local\\Temp\\95a0f294-22c3-4e7c-b972-a575719f27cb_selenium-html.rar.selenium-html.rar\\selenium-html\\upload.html");3.6 浏览器参数设置
设置⽆头模式
无头模式(Headless Mode) 是浏览器的一种运行方式:它可以在不显示可视化界面(没有窗口、没有界面渲染) 的情况下,后台运行浏览器的核心功能(解析 HTML、执行 JS、发送网络请求等),默认情况下是有头模式
WebDriverManager.chromedriver().setup();ChromeOptions options =newChromeOptions();//设置无头模式 options.addArguments("--headless"); options.addArguments("--remote-allow-origins=*");WebDriver driver =newChromeDriver(options); driver.get("https://www.baidu.com");设置浏览器加载策略
若页面资源比较多,通过driver.get方法去请求页面需要请求很长时间,就存在这样的要求:页面主要框架加载完了就继续往下执行,而不是等待所有的资源加载完成
//设置浏览器加载策略 options.setPageLoadStrategy(PageLoadStrategy.NONE);setPageLoadStrategy有三个可选参数:
- NONE: 完全不阻塞等待Webdriver
- EAGER: DOM访问准备就绪,但是还是存在其他资源还在加载(注入图像…)
NORMAL: 默认值等待所有资源下载完成
