工作中Selenium常用方法汇总java版(工作笔记)

Selenium是一个自动化测试框架。它可以通过操作一个驱动程序,模拟用户在浏览器上浏览网页的行为。一般是用来做自动化测试的。其实也可以用它来做网络爬虫(速度贼慢,也容易出现莫名其妙的错误)。

驱动下载

Selenium是通过驱动来操作控制浏览器的的。所以在使用前需要针对不同的浏览器平台下载对应的浏览器驱动。
所以除了代码外,还需要准备两个东西:1、是安装浏览器(如火狐、chrome等);2、下载浏览器对应的驱动。

注意浏览器跟驱动的版本哦。有时候会因为版本不匹配而出现莫名其妙的错误。
如果谷歌浏览器驱动下载太慢,可以考虑去淘宝镜像下载。
其他浏览器(比如IE、Edge)也有对应的驱动,但是我不提供下载链接。哈哈问度娘吧。因为,我不怎么用。

Quick Start

一个小程序就能快速的入门并且使用Selenium进行玩耍了。

  1. 新建Maven项目导入Selenium包
<dependencies>
    <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-chrome-driver -->
    <!--谷歌浏览器-->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-chrome-driver</artifactId>
        <version>3.141.59</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>3.141.59</version>
    </dependency>
    <!--测试用-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>compile</scope>
    </dependency>
</dependencies>
  1. 安装谷歌浏览器。(本次测试使用的是:81.0.4044.138正式版)
  2. 下载谷歌浏览器驱动。把下载好的chromedriver.exe放在D盘。(测试使用的是83.0.4103.39版本)
  3. 写代码(JDK版本1.8)
    import org.junit.Test;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.chrome.ChromeDriver;
    
    public class MyTest {
        @Test
        public void run(){
            //设置驱动的路径
            System.setProperty("webdriver.chrome.driver", "D:\chromedriver.exe");
            WebDriver driver=new ChromeDriver();
            //打开百度
            driver.get("https://www.baidu.com");
        }
    }
    

运行上面的程序你会看到你的谷歌浏览器自动打开了,还莫名其妙的进入了百度这个莫名其妙的主页。
接下来你就会用Selenium了,我们来介绍一下工作中常用到的API。( ^ _ ^ )....

浏览器控制

  • 打开网址

    //访问https://www.baidu.com这个网址
    driver.get("https://www.baidu.com");
    

    这就相当于你打开浏览器,在输入框中输入https://www.baidu.com然后回车。

  • 设置浏览器的大小
    等于手动放大缩小浏览器到指定大小

    //将打开的浏览器设置成100*100大小
    driver.manage().window().setSize(new Dimension(100,100));
    
  • 浏览器最大化

    driver.manage().window().maximize();
    
  • 全屏显示

    driver.manage().window().fullscreen();
    

    全屏显示和浏览器最大化的区别,就是。最大化相当于点击浏览器右上方的“口”最大化浏览器。而全屏显示相当于按了键盘上的F11(不知道效果的可以打开个浏览器,然后按F11试试看)。

  • 设置浏览器的位置

    //设置浏览器的位置坐标为(0,50)
    driver.manage().window().setPosition(new Point(0,50));
    

    这个坐标指的是浏览器左上角的那个点。在整个屏幕中的位置。

  • 退出

    //你懂得。相当于点右上角的:x
    driver.quit();
    

除了设置浏览器的大小和位置,还可以通过getSize()getPosition()来获取浏览的的大小和位置。用法类似。

页面操作

上面介绍了浏览器的操作,下面用介绍一下页面的操作。

  • 后退操作
    //后退操作:<-
    driver.navigate().back();
    
  • 前进操作
    //前进操作:->
    driver.navigate().forward();
    
  • 刷新操作
    //等于按F5刷新
    driver.navigate().refresh();
    
  • 跳转到某一页
    //首先打开本地的一个html文件,然后跳转到百度页面。
    driver.get("file:///C:/Users/czx/Desktop/File/Test/test.html");
    driver.navigate().to("https://www.baidu.com");
    

    其实这两个方法看上去功能相似,具体的区别我还没发现。

获取页面信息

  • 获取页面标题

    driver.get("https://www.baidu.com");
    driver.getTitle();
    //getTitle()返回的结果是:百度一下,你就知道
    
  • 获取当前页面的url

    driver.getCurrentUrl();
    //获取url地址
    
  • 获取整个页面的HTML内容

    driver.getPageSource()
    

    会把整个页面的数据都返回。

页面元素选择器

  • id选择器

    //java
    driver.findElement(By.id("divId"));
    
    <!--html-->
    <div id="divId"></div>
    
  • name选择器

    //java
    driver.findElement(By.name("divName"));
    
    <!--html-->
    <div name="divName"></div>
    
  • linkText选择器

    //java
    driver.findElement(By.linkText("百度a"));
    
    <!--html-->
    <a href="https://www.baidu.com">百度a</a>
    
  • partialLink选择器
    跟上面的linkText很相似,不过partialLink可以匹配部分链接文字

    //java
    driver.findElement(By.linkText("百"));
    driver.findElement(By.linkText("度"));
    driver.findElement(By.linkText("度a"));
    //三个返回的结果是一样的
    
    <!--html-->
    <a href="https://www.baidu.com">百度a</a>
    
  • tag选择器

    //java
    driver.findElement(By.TagName("div"));
    
    <!--html-->
    <div></div>
    
  • class选择器

    //java
    driver.findElement(By.className("class1"));
    driver.findElement(By.className("class2"));
    //注意这里是findElements多个s
    //此方法可以将所有class1都查询出来,返回一个List<WebElement>,会将下面两个div都返回。
    driver.findElements(By.className("class1"));
    
    <!--html-->
    <div class="class1"></div>
    <div class="class1 class2"></div>
    
  • css选择器
    有好几种写法

    //java
    driver.findElement(By.cssSelector("#divId"));
    driver.findElement(By.cssSelector(".class1"));
    driver.findElement(By.cssSelector("[name=divName]"));
    driver.findElement(By.cssSelector("div"));
    driver.findElement(By.cssSelector("html > body > div > a"));
    

    如果你熟悉css样式的写法的话,会对上面的内容比较清楚。

  • xpath选择器
    这个比较复杂,但是贼灵活

    //java
    driver.findElement(By.xpath("//*[@id='divId']"))
    driver.findElement(By.xpath("//*[@name='divName']"))
    driver.findElement(By.xpath("//input[@class='class1']"))
    driver.findElement(By.xpath("/html/body/form/span/input"))
    driver.findElement(By.xpath("//span[@class='class1']/input"))
    driver.findElement(By.xpath("//form[@id='form']/span/input"))
    driver.findElement(By.xpath("//input[@id='divId' and @name='divName']"))
    

以上api返回的都是一个元素,即:WebElement。如果匹配到多个元素那么默认返回第一个。想要获取多个元素,需要使用:driver.findElements(By....);此方法返回的是List<WebElement>

对DOM元素的操作

上面的选择器方法可以在页面上获取一DOM元素,也就是WebElement对象。下面是对这些对象进行操作的API。

  • 获取文本内容

    WebElement element=driver.findElement(By.id("divId"));
    String text = element.getText();
    //text的值是:dbwos
    
    <!--html-->
    <div id="divId">dbwos</div>
    
  • 清空文本输入框的内容

    WebElement element=driver.findElement(By.id("inputId"));
    element.clear();
    //会将下面的TEST清除掉。
    
    <!--html-->
    <input id="inputId" value="TEST"/>
    
  • 模拟键盘输入值
    登录的时候需要输入用户名或者密码或则验证码吧,这个就是模拟这个操作的。

    element.sendKeys("zhangsan");
    
  • 模拟鼠标点击

    //打开一个本地html文件
    driver.get("file:///D:/test.html");
    WebElement element=driver.findElement(By.tagName("button"));
    element.click();
    
    <!--html-->
    <button onclick="alert('我被点击了')">click me</button>
    

    上面的例子会弹出:我被点击了。

  • 表单提交
    在登录的时候,大多数都有个登录的按钮。一般这个按钮不是submit提交表单,就是监听单机click事件

    element.submit();
    

执行Javascript代码

无论使用Selenimu进行自动化测试还是爬虫实验,都经常会需要执行js代码来做一些页面操作。

  • 执行异步js代码

    //使用JS在控制台输出了一句:Hello Selenium!
    String javascriptCode="console.log('Hello Selenium!');";
    ((JavascriptExecutor)driver).executeScript(javascriptCode);
    

    同样可以使用jQuery等js库来操作。但是注意:一定要等网页把jQuery.js加载完成再调用才可以。要不会报错。(这个跟直接写js原理一样,需要加载完成才能使用)

  • 执行同步JS代码

    String javascriptCode="console.log('Hello Selenium!');";
    ((JavascriptExecutor)driver).executeAsyncScript(javascriptCode);
    

    同步执行脚本会阻塞当前线程,什么时候脚本执行完了才继续主线程的下面代码。

  • 保证JS库(如:jquery)加载完成
    有是有需要调用网页的js库,这时候为了避免报错,需要等待一会,让网页加载完成,js库下载完成。

    //进入这个莫名其妙的网站
    driver.get("https://www.dbwos.com");
    //将当前线程休眠3秒,让网站加载3秒。看看是否能加载完成。
    Threan.sleep(3000L);
    String javascriptCode="$('#divId').html('Hello!Selenium.');";
    ((JavascriptExecutor)driver).executeScript(javascriptCode);
    

    这种方法比较暴力,直接把执行线程休眠,来等待网页加载完成。

加载等待

有时候打开一个网页不能立即操作,要不会报错。比如找不到元素之类的。需要等待网页加载完成后再操作才可以。Selenium提供了两种加载等待方式-显式等待、隐式等待。

  • 显示等待
    通过WebDriverWait对象实现显示的加载等待

    public class MyTest {
      @Test
      public void run()throws InterruptedException{
          System.setProperty("webdriver.chrome.driver", "D:\chromedriver.exe");
          WebDriver driver=new ChromeDriver();
          driver.get("https://www.baidu.com");
          WebDriverWait wait=new WebDriverWait(driver,3000);
          wait.until(new ExpectedCondition<WebElement>() {
              public WebElement apply(WebDriver driver) {
                  return driver.findElement(By.id("kw"));
              }
          }).sendKeys("dbwos");
    
      }
    }
    //上面的例子实现了再3秒内等待百度加载,如果再3秒内能找到id是“kw”的元素那么输入“dbows”这几个字母。
    

    上面的例子每隔0.5秒回查找这个kw元素是否存在。如果存在就返回。如果3秒后还没找到,集抛出异常。
    其实WebDriverWait还有一个构造方法new WebDriverWait(driver,3000,500);,其实上面的构造方法也是调用的这个,不过把第三个参数设置成默认的500毫秒。

  • 隐式等待
    页面加载超时时间

    //3秒页面加载不完成就报异常
    driver.manage().timeouts().pageLoadTimeout(3,TimeUnit.SECONDS);
    driver.get("https://www.baidu.com");
    

    查找元素超时时间

    //三分钟内找不到id是kw的元素就报异常
    driver.manage().timeouts().pageLoadTimeout(3,TimeUnit.MINUTES);
    driver.findElement(By.id("kw"));
    

    异步脚本执行超时

    //3分钟这个脚本还没执行完就报异常
    driver.manage().timeouts().setScriptTimeout(3,TimeUnit.MINUTES);
    String javascriptCode="$('#divId').html('Hello!Selenium.');";
    ((JavascriptExecutor)driver).executeScript(javascriptCode);
    

    为什么是异步脚本?因为执行的要是同步脚本,回阻塞当前线程。什么时候脚本执行完什么时候继续。就不存在这个超时的问题。

  • JAVA线程等待
    除了上面两种,我们还可以使用Java的线程操作来实现等待网页加载完成。

    public class MyTest {
      @Test
      public void run()throws InterruptedException{
          System.setProperty("webdriver.chrome.driver", "D:\chromedriver.exe");
          WebDriver driver=new ChromeDriver();
          driver.get("https://www.dbwos.com");
          Thread.sleep(3000L);
          driver.findElement(By.tagName("input"));
          driver.quit();
      }
    }
    

其他操作

有是有需要对浏览器的页面截图。Selenium提供了屏幕截图的API。

  • 浏览器屏幕截图
    //将百度页面截图保存到d盘下的screenSnapshot.jpg文件。
    driver.get("https://www.baidu.com");
    File srcFile =((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
    try{
        FileCopyUtils.copy(srcFile,new File("d:\screenSnapshot.jpg"));
    }catch (IOException e){
        e.printStackTrace();
    }
    
  • 设置代理
    如果用java+selenium写爬虫程序,就可能会需要设置代理。
    String httpProxy="<HOST:PORT>";//代理的地址和端口号
    String sslProxy="";
    String ftpProxy="";
    proxy.setHttpProxy(httpProxy);
    proxy.setSslProxy(sslProxy);
    proxy.setFtpProxy(ftpProxy);
    options.setCapability("proxy",proxy);
    WebDriver driver = new FirefoxDriver(options)
    

作者:BobC

文章原创。如你发现错误,欢迎指正,在这里先谢过了。博主的所有的文章、笔记都会在优化并整理后发布在个人公众号上,如果我的笔记对你有一定的用处的话,欢迎关注一下,我会提供更多优质的笔记的。
原文地址:https://www.cnblogs.com/Eastry/p/12887530.html