Java+Selenium设置元素等待的方法详解

 更新时间:2023年01月09日 09:01:54   作者:洛阳泰山  
本文主要介绍如何使用java代码利用Selenium操作浏览器,某些网页元素加载慢,如何操作元素就会把找不到元素的异常,此时需要设置元素等待,等待元素加载完,再操作,感兴趣的可以了解一下

简介

本文主要介绍如何使用java代码利用Selenium操作浏览器,某些网页元素加载慢,如何操作元素就会把找不到元素的异常,此时需要设置元素等待,等待元素加载完,再操作。

设置元素等待

很多页面都使用 ajax 技术,页面的元素不是同时被加载出来的,为了防止定位这些尚在加载的元素报错,可以设置元素等来增加脚本的稳定性。webdriver 中的等待分为 显式等待 和 隐式等待。

显式等待

显式等待:设置一个超时时间,每个一段时间就去检测一次该元素是否存在,如果存在则执行后续内容,如果超过最大时间(超时时间)则抛出超时异常(TimeoutException)。显示等待需要使用 WebDriverWait,同时配合 until 或 not until 。下面详细讲解一下。

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
 
 
/**
 * @author Lenovo
 */
public class SeleniumDemo {
    private final static String webDriver = "webdriver.chrome.driver";
    private final static String webDriverPath ="E:\\chromedriver\\chromedriver.exe";
 
    public static void main(String[] args) throws InterruptedException {
        System.setProperty(webDriver, webDriverPath);
        WebDriver driver= new ChromeDriver();
        //博客主页
        driver.get("https://blog.csdn.net/weixin_40986713");
        WebElement element=driver.findElement(By.className("submit"));
        long start=System.currentTimeMillis();
        //等待5秒
        WebDriverWait shortWait = new WebDriverWait(driver, 5);
        //5秒内元素加载出来就执行点击
        shortWait.until(ExpectedConditions.elementToBeClickable(element)).click();
        //忽略找不到元素异常
        shortWait.ignoring(NoSuchElementException.class);
        System.out.println("耗时 "+(System.currentTimeMillis()-start)+" ms");
    }
}
  • until 指定预期条件的判断方法,在等待期间,每隔一段时间调用该方法,判断元素是否存在,直到元素出现。
  • ignoring 指定忽略的异常,如果设定的执行等待超时的时间段内,忽略指定的异常,让程序继续进行。

隐式等待

隐式等待也是指定一个超时时间,如果超出这个时间指定元素还没有被加载出来,就会抛出 NoSuchElementException 异常。

除了抛出的异常不同外,还有一点,隐式等待是全局性的,即运行过程中,如果元素可以定位到,它不会影响代码运行,但如果定位不到,则它会以轮询的方式不断地访问元素直到元素被找到,若超过指定时间,则抛出异常。

使用 driver.manage().timeouts().implicitlyWait() 来实现隐式等待,使用难度相对于显式等待要简单很多。

示例:打开个人主页,设置一个隐式等待时间 5s,通过 id 定位一个不存在的元素,最后打印 抛出的异常 与 运行时间。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
 
import java.util.concurrent.TimeUnit;
 
/**
 * @author Lenovo
 */
public class SeleniumDemo {
    private final static String webDriver = "webdriver.chrome.driver";
    private final static String webDriverPath ="E:\\chromedriver\\chromedriver.exe";
 
    public static void main(String[] args) throws InterruptedException {
        System.setProperty(webDriver, webDriverPath);
        WebDriver driver= new ChromeDriver();
        //博客主页
        driver.get("https://blog.csdn.net/weixin_40986713");
        //设置全局隐式等待
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        long start=System.currentTimeMillis();
        try {
            driver.findElement(By.className("tarzan"));
        }catch (Exception e){
            System.out.println(e);
            System.out.println("耗时 "+(System.currentTimeMillis()-start)+" ms");
        }
    }
}

代码运行到 driver.findElement(By.className("tarzan"));这句之后触发隐式等待,在轮询检查 5s 后仍然没有定位到元素,抛出异常。

强制等待

用java代码强制当前正在执行的线程休眠(暂停执行)

使用 time.sleep() 强制等待,设置固定的休眠时间,对于代码的运行效率会有影响。

以上面的例子作为参照,将 隐式等待 改为 强制等待。

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
 
 
/**
 * @author Lenovo
 */
public class SeleniumDemo {
    private final static String webDriver = "webdriver.chrome.driver";
    private final static String webDriverPath ="E:\\chromedriver\\chromedriver.exe";
 
    public static void main(String[] args) throws InterruptedException {
        System.setProperty(webDriver, webDriverPath);
        WebDriver driver= new ChromeDriver();
        //博客主页
        driver.get("https://blog.csdn.net/weixin_40986713");
        long start=System.currentTimeMillis();
        //等待5s
        Thread.sleep(5000);
        try {
            driver.findElement(By.className("tarzan"));
        }catch (Exception e){
            System.out.println(e);
            System.out.println("耗时 "+(System.currentTimeMillis()-start)+" ms");
        }
    }
}

值得一提的是,对于定位不到元素的时候,从耗时方面隐式等待和强制等待没什么区别。但如果元素经过 2s 后被加载出来,这时隐式等待就会继续执行下面的代码,但 sleep还要继续等待 3s。

总结

推荐使用的隐式等待,也就是implicitlyWait。

理由:

使用implicitlyWait或者明确等待(explicitly wait),方法参数是等待的最大时长。

也就是只要一找到元素,就会立刻执行下一行代码,不会强制等待参数里设置的时间。

而第三种(线程休眠)则不同,会强制等待设置的时间。设想一下,如果你的工程有好几百个case,

需要等待的元素都采用第三种,会大大加长所有case执行的时间,而你又急着要report,岂不是很惨。

使用implicitlyWait,webdriver会自动应用到case中的所有element中。在启动浏览器(driver.get)之后设置上,这样就不用针对某个元素去设置了,简直太方便了,不过有些特殊的元素,确实等待时间较长的,可以再采用explicit wait。

如果implicitlyWait和explicitly wait都在用在代码里,那么最大等待时间不是两个时间的叠加,而是取最大值。

到此这篇关于Java+Selenium设置元素等待的方法详解的文章就介绍到这了,更多相关Java Selenium设置元素等待内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot配置mybatis驼峰命名规则自动转换的实现

    SpringBoot配置mybatis驼峰命名规则自动转换的实现

    这篇文章主要介绍了SpringBoot配置mybatis驼峰命名规则自动转换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 使用IDEA开发配置Java Web的初始化过程

    使用IDEA开发配置Java Web的初始化过程

    该教程使用idea开发工具初始化javaweb项目,该运行在tomcat服务器上通过配置项目环境变量保证tomcat正常启动,具体操作配置教程参考下本文
    2021-06-06
  • Java中Controller引起的Ambiguous mapping问题及解决

    Java中Controller引起的Ambiguous mapping问题及解决

    这篇文章主要介绍了Java中Controller引起的Ambiguous mapping问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Java使用pulsar-flink-connector读取pulsar catalog元数据代码剖析

    Java使用pulsar-flink-connector读取pulsar catalog元数据代码剖析

    这篇文章主要介绍了Java使用pulsar-flink-connector读取pulsar catalog元数据代码剖析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • Spring Security基于json登录实现过程详解

    Spring Security基于json登录实现过程详解

    这篇文章主要介绍了Spring Security基于json登录实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • java返回前端树形结构数据的2种实现方式

    java返回前端树形结构数据的2种实现方式

    近期项目有个需求,需要将组织机构数据拼成树型结构返回至前端,下面这篇文章主要给大家介绍了关于java返回前端树形结构数据的2种实现方式,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-05-05
  • 详解Quartz 与 Spring框架集成的三种方式

    详解Quartz 与 Spring框架集成的三种方式

    这篇文章主要介绍了详解Quartz 与 Spring框架集成的三种方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • 详解Javaweb状态管理的Session和Cookie

    详解Javaweb状态管理的Session和Cookie

    这篇文章主要介绍了Javaweb状态管理的Session和Cookie,将浏览器与web服务器之间多次交互当做一个整体来处理,并且多次交互所涉及的数据(状态)保存下来,需要的朋友可以参考下
    2023-05-05
  • 使用spring mail发送html邮件的示例代码

    使用spring mail发送html邮件的示例代码

    本篇文章主要介绍了使用spring mail发送html邮件的示例代码,这里整理了详细的示例代码,具有一定的参考价值,有兴趣的可以了解一下
    2017-09-09
  • Java自定义equals产生的问题分析

    Java自定义equals产生的问题分析

    这篇文章主要介绍了Java自定义equals时super.equals带来的问题分析,总的来说这并不是一道难题,那为什么要拿出这道题介绍?拿出这道题真正想要传达的是解题的思路,以及不断优化探寻最优解的过程。希望通过这道题能给你带来一种解题优化的思路
    2023-01-01

最新评论