Java + Selenium 元素等待工具类

我们平常在使用selenium爬虫的时候,通常会遇到登录这个操作,然鹅登录的时候,如果对方服务器反应时间太久,或者太快,时间不稳定,那么此时进行登录验证,密码是否正确,信息是否填对的时候,就会非常麻烦。

在我查阅大量资料过后,仍然找不到满意的元素等待方法,所以索性自己实现一个,在这里分享给大家。

函数说明

函数 说明
waitElement() 等待指定元素。传入WebDriver 对象,和selenium的By对象。如果对象存在,执行回调,或者抛出异常
waitUrl() 等待指定网页。传入WebDriver 对象,和网页url。如果对象存在,执行回调,或者抛出异常
waitElementText() 等待指定元素的文本。传入WebDriver 对象,和selenium的By对象,还有要判断的文文本。如果文本存在,执行回调,或者抛出异常

源码

主类

/**
 * @Author: KL-Skeleton
 * @Description: ${Description}
 * @Date: Created in 19:22 2020/8/27
 */
public class ElementTimeOutUtils {
    
    
//线程的超时时间默认为一分钟
    private static long runnable_timeout = 60*1000;
    /**
     *线程池
     */
    private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

    //抛出错误的语句
    private  static  String exceptionStr(WebDriver driver,Object by){
    
    
        return "the " + driver + " time out waiting for the element(" + by+")";
    }

    //元素等待
    public static void waitElement(WebDriver driver, By by, long time) throws ElementTimeOutException {
    
    

        long beginTime = System.currentTimeMillis();
        //如果当前时间减去开始的时间,小于time,并且传入的等待条件不符合,那么将一直堵塞此进程,直到超时,或者条件符合即可。
        while ((System.currentTimeMillis()-beginTime<time)&&(driver.findElements(by).size()==0)){
    
    }
        if(System.currentTimeMillis()-beginTime>=time){
    
    
            throw new ElementTimeOutException(exceptionStr(driver,by));
        }

    }

    public static void waitElement(WebDriver driver, By by,MyRunnable runnable){
    
    
        cachedThreadPool.execute(()->{
    
    
            long beginTime = System.currentTimeMillis();
            //如果当前时间减去开始的时间,小于time,并且传入的等待条件不符合,那么将一直堵塞此进程,直到超时,或者条件符合即可。
            while ((System.currentTimeMillis()-beginTime<runnable_timeout)&&(driver.findElements(by).size()==0)){
    
    }
            if(System.currentTimeMillis()-beginTime<runnable_timeout){
    
    
                runnable.run();
            }else  {
    
    
                runnable.timeout();
            }
        });

    }


    //网页等待
    public static void waitUrl(WebDriver driver,String url,long time) throws ElementTimeOutException{
    
    
        long beginTime = System.currentTimeMillis();
        //如果当前时间减去开始的时间,小于time,并且传入的等待条件不符合,那么将一直堵塞此进程,直到超时,或者条件符合即可。
        while ((System.currentTimeMillis()-beginTime<time)&&(!driver.getCurrentUrl().contains(url))){
    
    }
        if(System.currentTimeMillis()-beginTime>=time){
    
    
            throw new ElementTimeOutException(exceptionStr(driver,url));
        }
    }


    public static void waitUrl(WebDriver driver, String url, MyRunnable runnable){
    
    
        cachedThreadPool.execute(()->{
    
    
            long beginTime = System.currentTimeMillis();
            //如果当前时间减去开始的时间,小于time,并且传入的等待条件不符合,那么将一直堵塞此进程,直到超时,或者条件符合即可。
            while ((System.currentTimeMillis()-beginTime<runnable_timeout)&&(!driver.getCurrentUrl().contains(url))){
    
    }
            if(System.currentTimeMillis()-beginTime<runnable_timeout) {
    
    
                runnable.run();
            }else {
    
    
                runnable.timeout();
            }
        });
    }

    //文本等待
    public static void waitElementText(WebDriver driver, By by, String text, long time) throws ElementTimeOutException{
    
    
        long beginTime = System.currentTimeMillis();
        //如果当前时间减去开始的时间,大于time,并且传入的布尔值为false。则抛出异常。
        while ((System.currentTimeMillis()-beginTime<time)&&(!driver.findElements(by).get(0).getText().contains(text))){
    
    }
        if(System.currentTimeMillis()-beginTime>=time){
    
    
            throw new ElementTimeOutException(exceptionStr(driver,by+" and text:"+text));
        }
    }


    public static void waitElementText(WebDriver driver,  By by,String text,MyRunnable runnable){
    
    
        cachedThreadPool.execute(()->{
    
    
            long beginTime = System.currentTimeMillis();
            //如果当前时间减去开始的时间,小于time,并且传入的等待条件不符合,那么将一直堵塞此进程,直到超时,或者条件符合即可。
            while ((System.currentTimeMillis()-beginTime<runnable_timeout)&&(!driver.findElements(by).get(0).getText().contains(text))){
    
    }
            if(System.currentTimeMillis()-beginTime<runnable_timeout){
    
    
                runnable.run();
            } else  {
    
    
                runnable.timeout();
            }
        });
    }

    //geter and seter
    public static long getRunnable_timeout() {
    
    
        return runnable_timeout;
    }

    public static void setRunnable_timeout(long runnable_timeout) {
    
    
        ElementTimeOutUtils.runnable_timeout = runnable_timeout;
    }

    public abstract static class MyRunnable{
    
    
        public void run(){
    
    }
        public void timeout(){
    
    }
    }





}

异常类

public   class ElementTimeOutException extends  Exception{
    
    
    public ElementTimeOutException() {
    
    
        super();
    }

    public ElementTimeOutException(String message) {
    
    
        super(message);
    }
}

使用示例

百度模拟搜索,搜索框输入“a”,然后点击搜索,直到底部元素“content_bottom”加载完成,即可实现回调,如果因为网络原因搜索缓慢超过1分钟,或者元素“content_bottom”始终找不到,则执行timeout回调。

public static void main(String[] args) {
    
    

        System.setProperty("webdriver.chrome.driver","C:\\Users\\ASUS\\Desktop\\chromedriver7.9.exe");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.baidu.com/");
        driver.findElement(By.id("kw")).sendKeys("a");
        driver.findElement(By.id("su")).click();
        //方法一:开启元素等待线程,最大等待时间默认为1分钟,这里可以设置为10秒,
        //优点:不会阻塞进程
        ElementTimeOutUtils.setRunnable_timeout(10*1000);
        ElementTimeOutUtils.waitElement(driver, By.id("content_bottom"), new ElementTimeOutUtils.MyRunnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("百度搜索加载成功");
            }
            @Override
            public void timeout() {
    
    
                super.timeout();
                System.out.println("百度搜索加载失败");
            }
        });

        //方法二:不开启线程,指定超时时间5秒,如果超时,则抛出异常
        //缺点:会阻塞进程
        try {
    
    
            ElementTimeOutUtils.waitElement(driver, By.id("content_bottoms"),5000);
            System.out.println("百度搜索加载成功");
        } catch (ElementTimeOutException e) {
    
    
            System.out.println("百度搜索加载失败");
            e.printStackTrace();
        }

    }

运行结果:
在这里插入图片描述

  • 同理也可以用来判断登录的时候,账号密码是否错误,等等
TimeOutUtil.waitElementText(driver, By.id("show_error"),"验证码错误", new TimeOutUtil.MyRunnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("验证码错误");
            }
        });

猜你喜欢

转载自blog.csdn.net/qq_31254489/article/details/108267115