❄️目录❄️

出现了找不到页面元素的问题,可能的原因有哪些?
1、元素复制错了
比如复制的元素是#s-hotsearch-wrapper > div,但是在粘贴的时候不小心多打了两个v成了#s-hotsearch-wrapper > divvv,页面没有这个元素就报错
2、元素定位方式使用错误,使用cssSelector却复制的xpath或者使用xpath却复制的是cssSelector。
cssSelector-->xpath, xpath-->cssSelector
3、自动化打开的页面和手工打开的页面不一样
4、动态元素
5、代码执行的速度比页面加载的速度要快。
也就是说我们查找的元素在页面中还没有加载出来的时候,代码却执行到了这一步,那么也会出现找不到页面元素的问题。
比如,我们在百度首页搜索"鞠婧祎"后点击这个"百度百科":
java
public class RunTest {
public static void main(String[] args) throws InterruptedException, IOException {
test_2026_01_06 test = new test_2026_01_06();
test.test01();
}
}
java
public class test_2026_01_06 {
public void test01() throws InterruptedException, IOException {
// 自动管理Chrome驱动,驱动程序下载驱动
// WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
//运行访问所有链接
options.addArguments("--remote-allow-origins=*");
//打开Chrome浏览器
WebDriver driver = new ChromeDriver(options);
//输入百度网址
driver.get("https://www.baidu.com");
//输入鞠婧祎并点击搜索
driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("鞠婧祎");
driver.findElement(By.cssSelector("#chat-submit-button")).click();
//没有等待
// Thread.sleep(3000);
//点击百度百科
driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")).click();
driver.quit();
}
}

我们可以看到程序报错,找不到我们复制的"百度百科"cssSelector,这就是因为页面元素还没有加载出来。
我们可以通过等待来解决这个问题。
等待
通常代码执行的速度比页面渲染的速度要快,如果避免因为渲染过慢出现的自动化误报的问题呢?可以使用selenium中提供的三种等待方法
强制等待
**Thread.sleep()**参数毫秒
针对上面的问题,当我们搜索"鞠婧祎"后我们强制等待页面元素加载3秒,再来看看是否报错:
java
public class test_2026_01_06 {
public void test01() throws InterruptedException, IOException {
// 自动管理Chrome驱动,驱动程序下载驱动
// WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
//运行访问所有链接
options.addArguments("--remote-allow-origins=*");
//options.addArguments("--start-maximized");
//options.addArguments("--no-sandbox");
//打开Chrome浏览器
WebDriver driver = new ChromeDriver(options);
//输入百度网址
driver.get("https://www.baidu.com");
//输入鞠婧祎并点击搜索
driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("鞠婧祎");
driver.findElement(By.cssSelector("#chat-submit-button")).click();
//等待3秒
Thread.sleep(3000);
//点击百度百科
driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")).click();
driver.quit();
}
}
可以看到程序正常运行完毕没有报错。
优点:使用简单,调试的时候比较有效
缺点:影响运行效率,浪费大量的时间。
智能等待
隐式等待
隐式等待是一种智能等待,在查找元素时,会在指定时间内不断查找,如果找到就继续执行后续代码,如果超时没有找到才会报错。
//隐式等待3秒 driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
implicitlyWait()参数是Duration类中提供的毫秒、秒、分钟等方法。
隐式等待会作用在页面的所有元素上 ,所以当写了隐式等待后,后续查找元素 (findElement(),findElements())时都会在指定时间内查找元素。只要driver对象没有被释放掉,那么隐式等待会一直生效。
但是隐式等待无法等待非页面元素,比如导航栏的前进、后退、刷新、弹窗......这些需要用显示等待。
显示等待
显示等待也是一种智能等待,在指定超时时间范围内满足操作的条件就能继续执行后续代码。
new WebDriverWait(driver, Duration.ofSeconds(3)).until($express)
返回值是boolean类型。
$express是操作的条件,涉及到selenium.support.ui.ExpectedConditions包下的ExpectedConditions类。
ExpectedConditions预定义方法的一些示例:
• elementToBeClickable(By locator) ‒ 用于检查元素的期望是可见的 并已启用,以便我们可以单击它。
• presenceOfElementLocated(Bylocator) ‒ 检查页面的 DOM 上是否存在元素 。(存在,但不保证元素是可见或者可点击的)
• textToBe(Bylocator,String str) -检查元素的文本内容完全匹配指定字符串。
• urlToBe(java.lang.String url) ‒ 检查当前页面的URL是一个特定的 URL
java
public class test_2026_01_06 {
public void test01() throws InterruptedException, IOException {
// 自动管理Chrome驱动,驱动程序下载驱动
// WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
//运行访问所有链接
options.addArguments("--remote-allow-origins=*");
//打开Chrome浏览器
WebDriver driver = new ChromeDriver(options);
//输入百度网址
driver.get("https://www.baidu.com");
//输入鞠婧祎并点击搜索
driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("鞠婧祎");
driver.findElement(By.cssSelector("#chat-submit-button")).click();
//强制等待3秒
//Thread.sleep(3000);
//隐式等待3秒
//driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
//点击百度百科
//driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")).click();
//显示等待3秒,然后点击百度百科
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#\\31 > div > div > div > div > div > div.new-tag_4ozgi.new-text-link_3k9GD > div > div.flex-wrapper-top_3ucFS > div.flex-col-left_3trtY.baike-wrapper_6AORN.cu-pt-xs-lg.baike-wrapper-pc_26R04.cu-pt-xl.baike-wrapper-left-pc_5eYY8.cos-space-pb-sm > div > div > p > span:nth-child(1) > span")));
driver.quit();
}
}
如果在规定时间内没有等待成功,则报错:

不能混合使用,可以配合使用
如果我们把隐式等待和显示等待混合使用会怎么样?
java
public class test_2026_01_06 {
public void test02() throws InterruptedException, IOException {
// 自动管理Chrome驱动,驱动程序下载驱动
// WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
//运行访问所有链接
options.addArguments("--remote-allow-origins=*");
//打开Chrome浏览器
WebDriver driver = new ChromeDriver(options);
//输入百度网址
driver.get("https://www.baidu.com");
//输入鞠婧祎并点击搜索
driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("鞠婧祎");
driver.findElement(By.cssSelector("#chat-submit-button")).click();
SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS");
System.out.println("开始等待前的时间:" + sim.format(System.currentTimeMillis()));
//隐式等待5秒
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
//显示等待10s
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
//等待一个不存在的元素
try {
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#\\3111111")));
} catch (Exception e) {
System.out.println("NoSuchElement!");
}
System.out.println("等待结束的时间:" + sim.format(System.currentTimeMillis()));
driver.quit();
}
}
public class RunTest {
public static void main(String[] args) throws InterruptedException, IOException {
test_2026_01_06 test = new test_2026_01_06();
test.test02();
}
}
多次执行看到总的等待时间不是5+10s,
所以我们不要混合使用隐式等待和显示等待,否则可能会导致等待时间不可预测。
但是我们可以配合两者使用,隐式等待只能作用在页面元素上不能等待非页面元素,而显示等待。
所以配合使用即隐式等待作用页面元素,显示等待作用在非页面元素上。
浏览器导航
打开网站
我们之前一直通过driver.get(url)来打开网站的,这是一种简洁的方式。
还有一种:driver.navigate().to(url)
前进后退刷新

//后退 driver.navigate().back(); //前进 driver.navigate().forward(); //刷新 driver.navigate().refresh();
弹窗
弹窗有3种,
警告弹窗
确认弹窗
提示弹窗
我们对弹窗的主要操作有点击确认、取消、输入文本信息、获取弹窗的文本信息。

但是弹窗在页面是找不到元素的,常规的selenium元素定位方法(xpath, cssSelector)失效,所以我们要通过selenim的Alert接口来操作弹窗

java
public class test_2026_01_06 {
/**
* 弹窗
*/
public void testAlert() throws InterruptedException {
// 自动管理Chrome驱动,驱动程序下载驱动
// WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
//运行访问所有链接
options.addArguments("--remote-allow-origins=*");
//打开Chrome浏览器
WebDriver driver = new ChromeDriver(options);
//打开含警告弹窗的页面
driver.get("file:///D:/My%20Professional%20Class/%E6%AF%94%E7%89%B9/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/selenium-html/selenium-html/alert.html#");
Thread.sleep(3000);
//点击,出现弹窗
driver.findElement(By.cssSelector("#tooltip")).click();
Thread.sleep(3000);
Alert alert = driver.switchTo().alert();
alert.accept();
Thread.sleep(3000);
driver.quit();
}
}
警告弹窗只要一个"确定"按钮,所以无论用accept()还是dismiss()都能达到关闭弹窗的作用。
自动化操作提示弹框输入文本内容时,界面上看不到输入效果,但实际上输入了文本信息。

java
public class test_2026_01_06 {
/**
* 弹窗
*/
public void testAlert() throws InterruptedException {
// 自动管理Chrome驱动,驱动程序下载驱动
// WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
//运行访问所有链接
options.addArguments("--remote-allow-origins=*");
//打开Chrome浏览器
WebDriver driver = new ChromeDriver(options);
//打开含 提示弹窗 的页面
driver.get("file:///D:/My%20Professional%20Class/%E6%AF%94%E7%89%B9/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/selenium-html/selenium-html/Prompt.html");
Thread.sleep(3000);
//点击,出现弹窗
driver.findElement(By.cssSelector("body > input[type=button]")).click();
Thread.sleep(1000);
Alert alert = driver.switchTo().alert();
//取消
alert.dismiss();
Thread.sleep(1000);
//点击,出现弹窗
driver.findElement(By.cssSelector("body > input[type=button]")).click();
//输入内容
alert.sendKeys("自动化测试");
Thread.sleep(1000);
//确定
alert.accept();
Thread.sleep(3000);
driver.quit();
}
}

另外,调起弹窗后必须将弹窗关闭才能对页面其它元素进行操作。
上传文件
点击文件上传的场景一般会弹出系统窗口让我们选择文件
但是selenium无法识别非web的控件,上传文件窗口为系统自带,无法识别窗口元素但是可以使用sendkeys来上传指定路径的文件,达到的效果是⼀样的
java
public class test_2026_01_06 {
/**
* 弹窗
*/
public void testAlert() throws InterruptedException {
// 自动管理Chrome驱动,驱动程序下载驱动
// WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
//运行访问所有链接
options.addArguments("--remote-allow-origins=*");
//打开Chrome浏览器
WebDriver driver = new ChromeDriver(options);
//打开本地含 上传文件 的页面
driver.get("file:///D:/My%20Professional%20Class/%E6%AF%94%E7%89%B9/%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/selenium-html/selenium-html/upload.html");
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
//找到选择文件元素并上传
driver.findElement(By.xpath("/html/body/div/div/input")).sendKeys("D:\\wangw\\Pictures\\Saved Pictures\\绿萝.jpg");
Thread.sleep(2000);
driver.quit();
}
}
可以看到我们手动上传和自动化上传文件的效果是一样的。

浏览器参数设置
1、无头模式
默认情况下是有头模式,写了这行代码就是无头模式:
//设置无头模式
options.addArguments("-headless");
那么什么是无头模式?
无头模式是一种浏览器运行模式,不显示图形用户界面(GUI),所有操作在后台静默执行。
所以无头模式下我们看不到任何前端运行效果。
实际在工作中,自动化在编写完成交付之后,每次执行的时候不会真的安排人一直肉眼盯着自动化的执行效果,一般自动化在实际运行中设置的都是无头模式,通过自动化执行的结果去分析。
2、浏览器加载策略
若页面资源比较多,通过driver.get方法去请求页面需要请求很长时间,因此就存在这样的要求:
页面主要框架加载完了就继续往下执行,而不是等待所有的资源加载完成。
Selenium 通过 PageLoadStrategy控制浏览器在何时认为页面已加载完成,从而决定是否继续执行后续操作。
该策略直接影响测试的速度 和稳定性,尤其在资源较多的页面中尤为重要

options.setPageLoadStrategy();
有3个参数可以设置,默认是 PageLoadStrategy.NORMAL,表示等待页面所有资源加载完成才往下执行。
EAGER表示DOM访问准备就绪,但是还存在其它资源还在加载(注入图像等)
NONE表示完全不阻塞webDriver,仅等待初始html文档加载完成。
因此在速度NONE>EAGER>NORMAL。速度越快,对页面完整性的保证越低。