工作中Selenium常用方法汇总java版(工作笔记)
Selenium是一个自动化测试框架。它可以通过操作一个驱动程序,模拟用户在浏览器上浏览网页的行为。一般是用来做自动化测试的。其实也可以用它来做网络爬虫(速度贼慢,也容易出现莫名其妙的错误)。
驱动下载
Selenium是通过驱动来操作控制浏览器的的。所以在使用前需要针对不同的浏览器平台下载对应的浏览器驱动。
所以除了代码外,还需要准备两个东西:1、是安装浏览器(如火狐、chrome等);2、下载浏览器对应的驱动。
- 各类浏览器平台下载地址
火狐浏览器驱动下载地址:geckodriver
谷歌浏览器驱动下载地址:ChromeDriver 、淘宝镜像
注意浏览器跟驱动的版本哦。有时候会因为版本不匹配而出现莫名其妙的错误。
如果谷歌浏览器驱动下载太慢,可以考虑去淘宝镜像下载。
其他浏览器(比如IE、Edge)也有对应的驱动,但是我不提供下载链接。哈哈问度娘吧。因为,我不怎么用。
Quick Start
一个小程序就能快速的入门并且使用Selenium进行玩耍了。
- 新建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>
- 安装谷歌浏览器。(本次测试使用的是:81.0.4044.138正式版)
- 下载谷歌浏览器驱动。把下载好的chromedriver.exe放在D盘。(测试使用的是83.0.4103.39版本)
- 写代码(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
文章原创。如你发现错误,欢迎指正,在这里先谢过了。博主的所有的文章、笔记都会在优化并整理后发布在个人公众号上,如果我的笔记对你有一定的用处的话,欢迎关注一下,我会提供更多优质的笔记的。