Window下环境配置
第一步:下载最新的chrome浏览器版本
第二步:查看版本 下载对应版本的ChromeDriver或下载对应版本的ChromeDrive
第三步:将下载好的ChromeDriver.exe文件放在Chrome的根目录下:
chrome更新很烦人:使用这个链接两个都能下载
第四步:配置环境变量:
右键点击我的电脑----->属性--->高级系统设置---->环境变量------>在path路径下添加上文中浏览器文件所在的根目录。我的是:C:\Program Files (x86)\Google\Chrome\Application
在浏览器输入:chrome://version
idea项目
mava依赖 查询对应版本(如果打不开就是你网络的问题建议使用热点)
org.seleniumhq.selenium selenium-java4.9.1 com.google.guava guava32.1.1-jre
测试是否搞定
import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import java.util.concurrent.TimeUnit; public class ChromeTest { public static void main(String[] args) throws InterruptedException { //启动chromedriver System.setProperty("webdriver.chrome.driver","C:\\xxxxxxx\\Application\\chromedriver.exe"); System.setProperty("webdriver.chrome.bin","C:\\xxxxxx\\Application\\chrome.exe"); WebDriver driver = new ChromeDriver(); driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); driver.get("https://www.baidu.com/"); driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS); driver.close(); } }
selenium(api方法)
加载驱动
//加载ChromeDriver 是使用chrome的条件
System.setProperty("webdriver.chrome.driver","C:\\xxxxxx\\Application\\chromedriver.exe");
添加chorme配置信息
设置浏览器文件默认下载路径
//创建ChromeOptions对象 ChromeOptions chromeOptions = new ChromeOptions(); //创建HashMap对象和指定下载路径 HashMapchromePrefs = new HashMap<>(); //设置默认下载路径 //禁止弹窗 chromePrefs.put("profile.default_content_settings.popups", 0); //下载地址 chromePrefs.put("download.default_directory", "C://xx//"); //禁止图片加载 chromePrefs.put("profile.managed_default_content_settings.images", 2); //创建WebDriver对象 WebDriver driver = new ChromeDriver(chromeOptions);
配置信息 常用设置(翻译版本)
ChromeOptions chromeOptions=new ChromeOptions(); //设置无头浏览器 //方法一:通过setHeadless方法直接设置 chromeOptions.setHeadless(true); //方法二:通过addArguments方法添加参数设置 chromeOptions.addArguments("--headless"); //启动最大化 chromeOptions.addArguments("--start-maximized"); //设置中文简体 chromeOptions.addArguments("--lang=zh-CN"); //关闭GPU 关闭图片渲染 chromeOptions.addArguments("--disable-gpu"); //设置浏览器打开窗口的大小,非必要属性 chromeOptions.addArguments("--window-size=1920,1080"); //打开控制台 chromeOptions.addArguments("--auto-open-devtools-for-tabs"); //消除安全校验 chromeOptions.addArguments("--allow-running-insecure-content");
浏览器驱动
WebDriver driver = new ChromeDriver(); //Chrome浏览器 WebDriver driver = new FirefoxDriver(); //Firefox浏览器 WebDriver driver = new EdgeDriver(); //Edge浏览器 WebDriver driver = new InternetExplorerDriver(); // Internet Explorer浏览器 WebDriver driver = new OperaDriver(); //Opera浏览器 WebDriver driver = new PhantomJSDriver(); //PhantomJS
selenium元素定位
- id
- name
- class name
- tag name
- link text
- partial link text
- xpath
- css selector
这8种定位方式在Java selenium中所对应的方法为:
- findElement(By.id())
- findElement(By.name())
- findElement(By.className())
- findElement(By.tagName())
- findElement(By.linkText())
- findElement(By.partialLinkText())
- findElement(By.xpath())
- findElement(By.cssSelector())
使用的实例
Title
我们的目的是要定位input标签的输入框。
- 通过id定位:
driver.findElement(By.id("kw"))- 通过name定位:
driver.findElement(By.name("wd"))- 通过class name定位:
driver.findElement(By.className("s_ipt"))- 通过tag name定位:
driver.findElement(By.tagName("input"))- 通过xpath定位,xpath定位有N种写法,这里列几个常用写法:
driver.findElement(By.xpath("//*[@id='kw']")); //获取任意id=kw的节点 driver.findElement(By.xpath("//*[@name='wd']")); //获取任意name=wd的节点 driver.findElement(By.xpath("//input[@class='s_ipt']")); //获取任意calss=s_ipt的节点 driver.findElement(By.xpath("/html/body/form/span/input")); //获取html->body->form->span->input节点 driver.findElement(By.xpath("//span[@class='soutu-btn']/input")); //获取任意class='soutu-btn'的span里的input节点 driver.findElement(By.xpath("//form[@id='form']/span/input")); //获取任意id="form"的表单下span下的input节点 driver.findElement(By.xpath("//input[@id='kw' and @name='wd']")); //获取任意id="kw"并且name="wd"的input节点 driver.findElement(By.xpath("//input[stars-with(@id,'ctrl')]")); //获取id以ctrl开头的input节点 driver.findElement(By.xpath("//input[ends-with(@id,'ctrl')]")); //获取id以ctrl结尾的input节点 driver.findElement(By.xpath("//input[contains(@id,'ctrl')]")); //获取id包含ctrl的input节点 driver.findElement(By.xpath("//td[@class='a1']/parent::tr")); //获取任意calss=a1的td节点的父级tr节点 driver.findElement(By.xpath("//td[@class='a3']/ancestor::div")); //获取任意calss=a3的td节点的所有父辈div节点 driver.findElement(By.xpath("//td[@class='a3']/ancestor-or-self::div")); //获取任意calss=a3的td节点以及它所有父辈div节点 driver.findElement(By.xpath("//tr[@class='a4']/descendant::td")); //获取任意calss=a4的tr节点的子td节点 driver.findElement(By.xpath("//tr[@class='a4']/descendant-or-self::td")); //获取任意calss=a4的tr节点和它的子td节点 driver.findElement(By.xpath("//tr[@class='a4']/preceding::span")); //获取任意calss=a4的tr节点开始标签之前的所有span节点(不包括自己和自己的子节点) driver.findElement(By.xpath("//tr[@class='a4']/preceding-sibling::span")); //获取任意calss=a4的tr节点开始标签之前的所有同级span节点 driver.findElement(By.xpath("//tr[@class='a4']/following::span")); //获取任意calss=a4的tr节点结束标签之后的所有span节点(不包括自己和自己的子节点) driver.findElement(By.xpath("//tr[@class='a4']/following-sibling::span")); //获取任意calss=a4的tr节点和之后的所有同级span节点- 通过css定位,css定位有N种写法,这里列几个常用写法:
driver.findElement(By.cssSelector("#kw"); driver.findElement(By.cssSelector("[name=wd]"); driver.findElement(By.cssSelector(".s_ipt"); driver.findElement(By.cssSelector("html > body > form > span > input"); driver.findElement(By.cssSelector("span.soutu-btn> input#kw"); driver.findElement(By.cssSelector("form#form > span > input"); 新闻hao123- 通过link text定位:
driver.findElement(By.linkText("新闻"); driver.findElement(By.linkText("hao123");- 通过partialLink text定位:
driver.findElement(By.partialLinkText("新"); driver.findElement(By.partialLinkText("hao"); driver.findElement(By.partialLinkText("123");
WebDriver
clear() 清除文本。
sendKeys(*value) 模拟按键输入。
click() 单击元素
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com/"); WebElement search_text = driver.findElement(By.id("kw")); WebElement search_button = driver.findElement(By.id("su")); search_text.sendKeys("Java"); search_text.clear(); search_text.sendKeys("Selenium"); search_button.click(); driver.quit();submit()方法用于提交表单。
WebElement search_text = driver.findElement(By.id("kw")); search_text.sendKeys("Selenium");search_text.submit();getSize() 返回元素的尺寸。
getText() 获取元素的文本。
getAttribute(name) 获得属性值。
isDisplayed() 设置该元素是否用户可见。
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com/"); //获得百度输入框的尺寸 WebElement size = driver.findElement(By.id("kw")); System.out.println(size.getSize()); //返回百度页面底部备案信息 WebElement text = driver.findElement(By.id("cp")); System.out.println(text.getText()); //返回元素的属性值, 可以是 id、 name、 type 或元素拥有的其它任意属性 WebElement ty = driver.findElement(By.id("kw")); System.out.println(ty.getAttribute("type")); //返回元素的结果是否可见, 返回结果为 True 或 False WebElement display = driver.findElement(By.id("kw")); System.out.println(display.isDisplayed()); driver.quit();
模拟鼠标操作
- contextClick() 右击
- clickAndHold() 鼠标点击并控制
- doubleClick() 双击
- dragAndDrop() 拖动
- release() 释放鼠标
- perform() 执行所有Actions中存储的行为
- ===============================
- Actions(driver) 调用Actions()类,将浏览器驱动driver作为参数传入。
- clickAndHold() 方法用于模拟鼠标悬停操作, 在调用时需要指定元素定位。
- perform() 执行所有ActionChains中存储的行为, 可以理解成是对整个操作的提交动作。
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com/"); WebElement search_setting = driver.findElement(By.linkText("设置")); Actions action = new Actions(driver); action.clickAndHold(search_setting).perform(); driver.quit(); ======================================================== Actions action = new Actions(driver); // 鼠标右键点击指定的元素 action.contextClick(driver.findElement(By.id("element"))).perform(); // 鼠标右键点击指定的元素 action.doubleClick(driver.findElement(By.id("element"))).perform(); // 鼠标拖拽动作, 将 source 元素拖放到 target 元素的位置。 WebElement source = driver.findElement(By.name("element")); WebElement target = driver.findElement(By.name("element")); action.dragAndDrop(source, target).perform(); // 释放鼠标 action.release().perform();
模拟键盘操作
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com"); WebElement input = driver.findElement(By.id("kw")); //输入框输入内容 input.sendKeys("seleniumm"); Thread.sleep(2000); //删除多输入的一个 m input.sendKeys(Keys.BACK_SPACE); Thread.sleep(2000); //输入空格键+“教程” input.sendKeys(Keys.SPACE); input.sendKeys("教程"); Thread.sleep(2000); //ctrl+a 全选输入框内容 input.sendKeys(Keys.CONTROL, "a"); Thread.sleep(2000); //ctrl+x 剪切输入框内容 input.sendKeys(Keys.CONTROL, "x"); Thread.sleep(2000); //ctrl+v 粘贴内容到输入框 input.sendKeys(Keys.CONTROL, "v"); Thread.sleep(2000); //通过回车键盘来代替点击操作 input.sendKeys(Keys.ENTER); Thread.sleep(2000); driver.quit(); ================================================================= sendKeys(Keys.BACK_SPACE) 回格键(BackSpace) sendKeys(Keys.SPACE) 空格键(Space) sendKeys(Keys.TAB) 制表键(Tab) sendKeys(Keys.ESCAPE) 回退键(Esc) sendKeys(Keys.ENTER) 回车键(Enter) sendKeys(Keys.CONTROL,‘a’) 全选(Ctrl + A) sendKeys(Keys.CONTROL,‘c’) 复制(Ctrl + C) sendKeys(Keys.CONTROL,‘x’) 剪切(Ctrl + X) sendKeys(Keys.CONTROL,‘v’) 粘贴(Ctrl + V) sendKeys(Keys.F1) 键盘 F1 ……sendKeys(Keys.F12) 键盘 F12
获取断言信息
- getTitle(): 用于获得当前页面的title。
- getCurrentUrl() : 用户获得当前页面的URL。
- getText() 获取页面文本信息。
//4、拿到结果
String pageSource = driver.getPageSource();
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com"); System.out.println("Search before================"); //获取当前的 title 和 url System.out.printf("title of current page is %s\n", driver.getTitle()); System.out.printf("url of current page is %s\n", driver.getCurrentUrl()); //百度搜索 WebElement search = driver.findElement(By.id("kw")); search.sendKeys("Selenium"); search.sendKeys(Keys.ENTER); Thread.sleep(2000); System.out.println("Search after================"); //获取当前的 title 和 url System.out.printf("title of current page is %s\n", driver.getTitle()); System.out.printf("url of current page is %s\n", driver.getCurrentUrl()); //获取第一条搜索结果的标题 WebElement result = driver.findElement(By.xpath("//div[@id='content_left']/div/h3/a")); System.out.println(result.getText()); driver.quit();
设置元素等待
显示等待
WebDriverWait类是由WebDirver提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。具体格式如下: WebDriverWait(driver, 10, 1) driver: 浏览器驱动。 10: 最长超时时间, 默认以秒为单位。 1: 检测的的间隔(步长) 时间, 默认为 0.5s。
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com"); //显式等待, 针对某个元素等待 WebDriverWait wait = new WebDriverWait(driver, 10, 1); wait.until(new ExpectedCondition() { @Override public WebElement apply(WebDriver text) { return text.findElement(By.id("kw")); } }).sendKeys("selenium"); driver.findElement(By.id("su")).click(); Thread.sleep(2000); driver.quit();
隐式等待
- implicitlyWait。识别对象时的超时时间。过了这个时间如果对象还没找到的话就会抛出NoSuchElement异常。
- setScriptTimeout。异步脚本的超时时间。WebDriver可以异步执行脚本,这个是设置异步执行脚本脚本返回结果的超时时间。
- pageLoadTimeout。页面加载时的超时时间。因为WebDriver会等页面加载完毕再进行后面的操作,所以如果页面超过设置时间依然没有加载完成,那么WebDriver就会抛出异常。
WebDriver driver = new ChromeDriver(); //页面加载超时时间设置为 5s driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS); driver.get("https://www.baidu.com/"); //定位对象时给 10s 的时间, 如果 10s 内还定位不到则抛出异常 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.findElement(By.id("kw")).sendKeys("selenium"); //异步脚本的超时时间设置成 3s driver.manage().timeouts().setScriptTimeout(3, TimeUnit.SECONDS); driver.quit();
多表单切换
在 Web 应用中经常会遇到 frame/iframe 表单嵌套页面的应用, WebDriver 只能在一个页面上对元素识别与 定位, 对于 frame/iframe 表单内嵌页面上的元素无法直接定位。 这时就需要通过 switchTo().frame()方法将当前定 位的主体切换为 frame/iframe 表单的内嵌页面中。
...
如果完成了在当前表单上的操作,则可以通过switchTo().defaultContent()方法跳出表单。
WebDriver driver = new ChromeDriver(); driver.get("http://www.126.com"); WebElement xf = driver.findElement(By.xpath("//*[@id='loginDiv']/iframe")); driver.switchTo().frame(xf); driver.findElement(By.name("email")).clear(); driver.findElement(By.name("email")).sendKeys("username"); driver.findElement(By.name("password")).clear(); driver.findElement(By.name("password")).sendKeys("password"); driver.findElement(By.id("dologin")).click(); driver.switchTo().defaultContent();
多窗口切换
在页面操作过程中有时候点击某个链接会弹出新的窗口, 这时就需要主机切换到新打开的窗口上进行操作。WebDriver提供了switchTo().window()方法可以实现在不同的窗口之间切换。 以百度首页和百度注册页为例,在两个窗口之间的切换。
- getWindowHandle(): 获得当前窗口句柄。
- getWindowHandles(): 返回的所有窗口的句柄到当前会话。
- switchTo().window(): 用于切换到相应的窗口,与上一节的switchTo().frame()类似,前者用于不同窗口的切换, 后者用于不同表单之间的切换。
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com"); //获得当前窗口句柄 String search_handle = driver.getWindowHandle(); //打开百度注册窗口 driver.findElement(By.linkText("登录")).click(); Thread.sleep(3000); driver.findElement(By.linkText("立即注册")).click(); //获得所有窗口句柄 Sethandles = driver.getWindowHandles(); //判断是否为注册窗口, 并操作注册窗口上的元素 for (String handle : handles) { if (handle.equals(search_handle) == false) { //切换到注册页面 driver.switchTo().window(handle); System.out.println("now register window!"); Thread.sleep(2000); driver.findElement(By.name("userName")).clear(); driver.findElement(By.name("userName")).sendKeys("user name"); driver.findElement(By.name("phone")).clear(); driver.findElement(By.name("phone")).sendKeys("phone number"); //...... Thread.sleep(2000); //关闭当前窗口 driver.close(); } } Thread.sleep(2000); driver.quit();
下拉框选择
Select类用于定位select标签。 selectByValue()方法符用于选取标签的value值。
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com"); driver.findElement(By.linkText("设置")).click(); driver.findElement(By.linkText("搜索设置")).click(); Thread.sleep(2000); //标签的下拉框选择 WebElement el = driver.findElement(By.xpath("//select")); Select sel = new Select(el); sel.selectByValue("20"); Thread.sleep(2000); driver.quit();
警告框处理
在 WebDriver中处理JavaScript所生成的alert、confirm以及prompt十分简单,具体做法是使用switch_to_alert()方法定位到alert/confirm/prompt,然后使用text/accept/dismiss/sendKeys等方法进行操作。
- getText(): 返回 alert/confirm/prompt 中的文字信息。
- accept(): 接受现有警告框。
- dismiss(): 解散现有警告框。
- sendKeys(keysToSend): 发送文本至警告框。
- keysToSend: 将文本发送至警告框。
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com"); driver.findElement(By.linkText("设置")).click(); driver.findElement(By.linkText("搜索设置")).click(); Thread.sleep(2000); //保存设置 driver.findElement(By.className("prefpanelgo")).click(); //接收弹窗 driver.switchTo().alert().accept(); Thread.sleep(2000); driver.quit();
文件上传
对于通过input标签实现的上传功能,可以将其看作是一个输入框,即通过sendKeys()指定本地文件路径的方式实现文件上传。 创建upfile.html文件,代码如下:
upload_file upload_file
WebDriver driver = new ChromeDriver(); File file = new File("./HTMLFile/upfile.html"); String filePath = file.getAbsolutePath(); driver.get(filePath); //定位上传按钮, 添加本地文件 driver.findElement(By.name("file")).sendKeys("D:\\upload_file.txt"); Thread.sleep(5000); driver.quit();
浏览器cookie操作
有时候我们需要验证浏览器中Cookie是否正确, 因为基于真实Cookie的测试是无法通过白盒测试和集成测试进行的。WebDriver提供了操作Cookie的相关方法可以读取、 添加和删除Cookie信息。 WebDriver 操作Cookie的方法:
- getCookies() 获得所有 cookie 信息。
- getCookieNamed(String name) 返回字典的key为“name”的Cookie信息。
- addCookie(cookie dict) 添加Cookie。“cookie_dict”指字典对象,必须有 name和value值。
- deleteCookieNamed(String name) 删除Cookie 信息。 “name”是要删除的 cookie的名称; “optionsString” 是该Cookie的选项,目前支持的选项包括“路径” , “域” 。
- deleteAllCookies() 删除所有 cookie 信息。
下面通过 geCookies()来获取当前浏览器的 cookie 信息。
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com"); Cookie c1 = new Cookie("name", "key-aaaaaaa"); Cookie c2 = new Cookie("value", "value-bbbbbb"); driver.manage().addCookie(c1); driver.manage().addCookie(c2); //获得 cookie Setcoo = driver.manage().getCookies(); System.out.println(coo); //删除所有 cookie driver.manage().deleteAllCookies(); driver.quit();
调用JavaScript代码
虽然WebDriver提供了操作浏览器的前进和后退方法,但对于浏览器滚动条并没有提供相应的操作方法。在这种情况下,就可以借助JavaScript来控制浏览器的滚动条。WebDriver提供了executeScript()方法来执行JavaScript代码。 用于调整浏览器滚动条位置的JavaScript代码如下:
window.scrollTo(0,450);window.scrollTo()方法用于设置浏览器窗口滚动条的水平和垂直位置。方法的第一个参数表示水平的左间距,第二个参数表示垂直的上边距。其代码如下:
WebDriver driver = new ChromeDriver(); //设置浏览器窗口大小 driver.manage().window().setSize(new Dimension(700, 600)); driver.get("https://www.baidu.com"); //进行百度搜索 driver.findElement(By.id("kw")).sendKeys("webdriver api"); driver.findElement(By.id("su")).click(); Thread.sleep(2000); //将页面滚动条拖到底部 ((JavascriptExecutor) driver).executeScript("window.scrollTo(100,450);"); Thread.sleep(3000); driver.quit();
获取窗口截图
自动化用例是由程序去执行,因此有时候打印的错误信息并不十分明确。如果在脚本执行出错的时候能对当前窗口截图保存,那么通过图片就可以非常直观地看出出错的原因。 WebDriver提供了截图函数getScreenshotAs()来截取当前窗口。
//最大化窗口
driver.manage().window().maximize(); //最大化窗口
WebDriver driver = new ChromeDriver(); driver.get("https://www.baidu.com"); File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); try { FileUtils.copyFile(srcFile, new File("d:\\screenshot.png")); } catch (IOException e) { e.printStackTrace(); } driver.quit();
获取后台的响应数据
commons-io commons-io2.6
package org.example.chrome.test; import org.apache.commons.io.FilenameUtils; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.devtools.DevTools; import org.openqa.selenium.devtools.v85.network.Network; import org.openqa.selenium.devtools.v85.network.model.RequestId; import org.openqa.selenium.remote.RemoteWebDriver; import java.io.FileOutputStream; import java.io.IOException; import java.util.*; public class Test1 { //计数器 public static Integer integer = 0; public static void main(String[] args) throws InterruptedException { // 设置 ChromeDriver 路径 System.setProperty("webdriver.chrome.driver", "C:xxx\\Application\\chromedriver.exe"); ChromeOptions options = new ChromeOptions(); options.setBinary("C:xxx\\Application\\chrome.exe"); // 创建 ChromeDriver 并传入 ChromeOptions RemoteWebDriver driver = new ChromeDriver(options); // 启用 Chrome DevTools DevTools devTools = ((ChromeDriver) driver).getDevTools(); devTools.createSession(); //监听器 devTools.addListener(Network.responseReceived(), responseReceived -> { RequestId requestId = responseReceived.getRequestId(); Network.GetResponseBodyResponse response = devTools.send(Network.getResponseBody(requestId)); //获取url的文件名 String name = FilenameUtils.getName(responseReceived.getResponse().getUrl()); if (name.equals("要下载的文件名")) { FileOutputStream fileOutputStream = null; try { //下载地址 fileOutputStream = new FileOutputStream("C:xxxxx\\resources\\" +name+integer, true); fileOutputStream.write(response.getBody().getBytes()); } catch (IOException e) { throw new RuntimeException(e); } finally { try { fileOutputStream.close(); } catch (IOException e) { throw new RuntimeException(e); } } integer=integer+1; } }); // 启用监听器 devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty())); // 访问目标网页 driver.get("https:xxxxurl"); //滚动条 Integer start = 0; Integer end = 500; while (true){ if (end == 30000){ break; } String s= "window.scrollTo("+start+","+end+")"; driver.executeScript(s); Thread.sleep(3000); start+=500; end+=500; } // 关闭浏览器 driver.quit(); } }