最近几个月在研究Selenium WebDriver,简单总结一下我的入坑记。
在配置Selenium的WebDriver前首先先选定测试的浏览器,IE、Chrome、Firefox等主流浏览器。不同的浏览器需要不同的驱动来实现。Firefox是自带驱动,不需要下载驱动,IE、Chrome等需要下载相应的驱动。
我使用的是Chrome,所以这里就只奉上Chromedriver了~链接:http://chromedriver.storage.googleapis.com/index.html。这个地址里面有所有Chrome版本对应的驱动,版本数越大表示版本越新。
下载驱动后,放到相应的文件夹下。
selenium-server-standalone包是Seleniumd的核心jar包,其中包含了各种元素定位和调用浏览器的方法。下载jar包后,在IDE中导入jar包就可以了。
在selenium中通常用findElement或findElements与By类结合来定位页面的元素,By类有8种常用的定位方式,如下:
测试页面源码:
<a id="wechatAuthorizationUrl" href="javascript:void(0)" onclick="show();" class="wechat" target="_parent">a>
点击页面中该元素的代码如下:
@Test
public void test_01_id() throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "/Users/nano/代码/Jessie/Driver/chromedriver");
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);
driver.get("https://passport.csdn.net/account/login?ref=toolbar");
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("wechatAuthorizationUrl")));
driver.findElement(By.id("wechatAuthorizationUrl")).click();
}
(之后的演示代码我就只贴操作的那部分代码啦)
id定位方法是通过元素的id属性来定位的,这个方法一般只适用于该页面中这个id是唯一的情况下。
测试页面源码:
id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
向页面中该输入框中输入字符:
driver.findElement(By.name("wd")).sendKeys("test");
通过元素的name属性来定位。
测试页面源码:
<a href="/" id="result_logo" onmousedown="return c({'fm':'tab','tab':'logo'})"><img src="//www.baidu.com/img/baidu_jgylogo3.gif" alt="到百度首页" title="到百度首页">a>
统计改页面中的a标签元素:
@Test
public void test03() throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "/Users/nano/代码/Jessie/Driver/chromedriver.exe");
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);
driver.get("https://www.baidu.com/");
wait.until(ExpectedConditions.presenceOfElementLocated(By.tagName("a")));
List a = driver.findElements(By.tagName("a"));
System.out.println(a.size()); //打印出a标签的个数
}
使用tagName方法来查找元素,一般元素都是不止一个,可以结合findElements方法和type属性来精准定位。
测试页面源码:
id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
使用className向输入框中传值
driver.findElement(By.className("s_ipt")).sendKeys("test1");
className属性是利用元素的css样式表所引用的伪类名称来进行元素查找的方法。
测试页面源码:
<a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻a>
点击页面中该元素:
driver.findElement(By.linkText("新闻")).click();
这个方法是通过页面中的超文本链接中的文字来定位元素,这种方式一般用于定位页面中的超文本链接。
测试页面源码同5。
点击页面中该元素
driver.findElement(By.partialLinkText("新")).click();
测试页面源码:
id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
向页面中该元素输入字符:
driver.findElement(By.xpath("//*[@id=\"kw\"]")).sendKeys("test2");
Xpath的定位方式是一个非常强大的定位方式,可以定位页面中几乎所有的元素。Xpath是XML path的简称,HTML文档本身是一个标准的XML页面,所以我们可以使用Xpath的语法来定位元素。不熟悉Xpath语法的人也完全不用担心,Chrome、Firefox浏览器中都可以复制Xpath路径,如下图:
![](/Users/nano/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/430f4205b2f8e1e38df458da0597a83d/Message/MessageTemp/96624a0fe103ddac70b33c322d8ec48d/Image/30431515140633_.pic_hd.jpg)
在Firefox中还可以使用插件firebug来查询到xpath路径。firebug复制出来的xpath路径是绝对路径,随着产品迭代可能会经常需要去修改绝对路径,所以推荐还是使用Chrome的相对路径。
Xpath除了能够精准定位,也支持模糊定位,可以用于源码中无标准元素或者元素标签不是唯一时。模糊定位主要有3种定位方式
测试页面源码:
<a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻a>
点击页面元素:
driver.findElement(By.xpath("//a[contains(@href, 'news')]")).click();
上面代码的含义是,在页面中寻找href属性值中包含“news”的所有a元素。@后面可以跟着寻找元素的任意属性名。
测试页面源码同上:
点击页面元素:
driver.findElement(By.xpath("//a[starts-with(@href, 'http://news')]")).click();
以上代码含义是,在页面中寻找href属性值中以“http://news”开头的所有a元素。@后面可以跟着寻找元素的任意属性名。
测试页面源码:
<a href="http://news.baidu.com" name="tj_trnews" class="mnav">新闻a>
点击页面元素:
driver.findElement(By.cssSelector("#u1 > a:nth-child(1)")).click();
cssSelector元素定位方式跟xpath类似,但执行速度较快,各种浏览器对它的支持都很到位,所以功能也比较强大。cssSelector的定位方式稍微有点复杂,需要进一步了解的可以自行Google一下。初学者可以使用右击—copy—Copy selector的方式来快速得到cssSelector路径。
![](/Users/nano/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/430f4205b2f8e1e38df458da0597a83d/Message/MessageTemp/9e20f478899dc29eb19741386f9343c8/Image/2581515169693_.pic_hd.jpg)
在浏览器中有些操作是使用系统原生的确认框,这时就无法通过定位元素的方式来操作我们需要的步骤。这种情况就要去操作浏览器的窗口来实现。
选择确认:
Alert al = driver.switchTo().alert();
al.accept();
选择取消:
Alert al = driver.switchTo().alert();
al.dismiss();
Alert al = driver.switchTo().alert();
al.accept();
driver.manage().window().maximize();
driver.quit();
driver.close();
driver.navigate().refresh();
driver.navigate().forward();
driver.navigate().back();
quit和close的区别在于,quit关闭整个浏览器的窗口;close关闭浏览器标签页。
在有些情况下,页面中的元素会被隐藏,需要鼠标点击或者悬停才能看到它隐藏的元素,这种情况下,需要对这些隐藏的元素做一些处理,使得我们可以任何情况下都能获取这些元素。
//处理隐藏元素的方法
Actions action = new Actions(driver);
WebElement nav = driver.findElement(By.xpath("//div[@id='appContentContainer']/div/div/div[1]/div[2]/div/div/button"));
//判断当nav元素出现时才执行相应的操作
if (nav.isDisplayed()) {
System.out.println("found it");
action.moveToElement(nav).build().perform();
}
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementById('appContentContainer').style.display='block';");
WebElement onElement1 = driver.findElement(By.xpath("(//ul[@class='dropdown-menu']/li)[last()]/a"));
action.moveToElement(onElement1).click().build().perform();
在使用selenium的过程中,等待web加载时,通常要等待下一个元素出现再进行操作,这个过程中需要用到等待。selenium中有3种等待:webDriverWait()、implicitly_wait()、sleep().
//引入前导入相应的包,单位为毫秒;
sleep(5);
//设置脚本在查找元素时的最大等待时间
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
//设置等待的时长,最长10S
WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[@id='appContentContainer']/div/div/div[1]/div[2]/div/div/button")));
先写这些吧,后续可能会继续增加~