目录
1引入jar包链接驱动,打开浏览器
2常用Webderver对象方法
3定位元素
4对页面元素进行操作
5iframe处理
6获得弹出窗口
7处理alert、confirm、prompt对话框
8操作cookies
9等待页面元素加载完成
10利用selenium-webdriver截图
背景
之 所以要学习selenium,是因为最近接到一项工作任务,爬取支付宝登录用户的数据,支付宝依然是通过cookie中的信息记录用户的状态,所以我只需 要获取支付宝完整的cookie就可以横行霸道,但这丫的反爬机制做的非常变态,在登录的过程中有大量的js计算以及js跳转,且在跳转的过程中创建 cookie,导致我获取的cookie不完全,被支付宝给拒绝访问,最后通过selenium模拟浏览器登录的方式解决
1引入jar包链接驱动,打开浏览器
(1)引入依赖
< dependency > < groupId >org.seleniumhq.selenium</ groupId > < artifactId >selenium-java</ artifactId > < version >2.53.0</ version > <!-- 对应火狐45.0.1版本 --> <!-- 对应chrome48至51版本 --> </ dependency > <!-- apache工具包 --> < dependency > < groupId >org.apache.commons</ groupId > < artifactId >commons-lang3</ artifactId > < version >3.4</ version > </ dependency > |
(2)创建不同版本的驱动,打开对应的浏览器,在此只介绍firefox和chrome的驱动链接,其他的如IE, HtmlUnit(×××面浏览器)等,可以查看链接http://www.51testing.com/html/05/n-2420905.html
chrome方式 (注:此为window平台,且要保证chrome浏览器安装在默认位置)
//设置chrome的全局参数 参数1为驱动类型 参数2为驱动位置 驱动下载地址https://pan.baidu.com/s/1bpgG98F System.setProperty( "webdriver.chrome.driver" , "D:/software/Applications/chromedriver.exe" ); //创建一个 ChromeDriver 的接口,用于连接 Chrome WebDriver webDriver= new ChromeDriver(); //进入百度 webDriver.get( "http://www.baidu.com" ); try { //睡眠3秒 TimeUnit.SECONDS.sleep( 3 ); } catch (InterruptedException e) { e.printStackTrace(); } //关闭浏览器 webDriver.quit(); |
firefox方式
//参数1为驱动类型 参数2为火狐浏览器的安装目录 浏览器下载地址http://ftp.mozilla.org/pub/firefox/releases/45.0/ System.setProperty( "webdriver.firefox.bin" , "D:/software/firefox45/firefox.exe" ); //创建一个 FirefoxDriver 的接口,用于连接 firefox WebDriver webDriver= new FirefoxDriver(); //进入百度 webDriver.get( "http://www.baidu.com" ); try { //睡眠3秒 TimeUnit.SECONDS.sleep( 3 ); } catch (InterruptedException e) { e.printStackTrace(); } //关闭浏览器 webDriver.quit(); |
2常用Webderver对象方法
此处以火狐接口为例,chrome通用
// 参数1为驱动类型 参数2为火狐浏览器的安装目录 浏览器下载地址http://ftp.mozilla.org/pub/firefox/releases/45.0/ System.setProperty( "webdriver.firefox.bin" , "D:/software/firefox45/firefox.exe" ); //创建一个 FirefoxDriver 的接口,用于连接 firefox WebDriver webDriver= new FirefoxDriver(); //(1)跳转路径→进入百度 webDriver.get( "http://www.baidu.com" ); //(2)导航路径→进入淘宝 webDriver.get()和webDriver.navigate().to()其实功能一样,只不过”get()”拼写起来更简单, //但是webDriver.navigate()可以控制浏览器的前进和后退 webDriver.navigate().to( "http://www.taobao.com" ); //(3)获取当前url String curUrl= webDriver.getCurrentUrl(); System.out.println(curUrl); //输出为:http://www.taobao.com //(4)获取当前页面标题 String curTitle=webDriver.getTitle(); System.out.println(curTitle); //输出为:淘宝网 - 淘!我喜欢 //(5)获取当前页面的html内容 String curHtml=webDriver.getPageSource(); System.out.println(curHtml); //输出太多··占位置··你们自己看吧 //(6)后退一页 webDriver.navigate().back(); //(7)前进一页 webDriver.navigate().forward(); //(8)返回当前的浏览器的窗口句柄 webDriver.getWindowHandle(); //(9)返回当前的浏览器的所有窗口句柄 webDriver.getWindowHandles(); try { //休眠3秒 TimeUnit.SECONDS.sleep( 3 ); } catch (InterruptedException e) { e.printStackTrace(); } //退出浏览器 webDriver.quit(); |
3定位元素
// 参数1为驱动类型 参数2为火狐浏览器的安装目录 浏览器下载地址http://ftp.mozilla.org/pub/firefox/releases/45.0/ System.setProperty( "webdriver.firefox.bin" , "D:/software/firefox45/firefox.exe" ); //创建一个 FirefoxDriver 的接口,用于连接 firefox WebDriver webDriver= new FirefoxDriver(); //(1)跳转路径→进入本文章页面 webDriver.get( "http://www.like666.com/2016/07/19/selenium-webdriver的简单操作说明/" ); try { //休眠3秒,等待元素加载完毕,后续有讲解其他方式等待元素加载 TimeUnit.SECONDS.sleep( 3 ); } catch (InterruptedException e) { e.printStackTrace(); } //WebDriver通过findElement()和findElements()获取单个以及多个元素,通过By对象来定位元素的位置,当没有获取到元素时 //,会引发org.openqa.selenium.NoSuchElementException异常,需要捕捉处理 //(1)className:此时获取类样式包含'hfeed'的元素 WebElement e1=webDriver.findElement(By.className( "hfeed" )); //获取该元素的id属性 System.out.println(e1.getAttribute( "id" )); //输出为page //(2)id:此时获取属性id='page'的元素 WebElement e2=webDriver.findElement(By.id( "page" )); //获取该元素的class属性 System.out.println(e2.getAttribute( "class" )); //输出为hfeed site //(3)cssSelector:此时获取包含类样式为hfeed的div元素 WebElement e3=webDriver.findElement(By.cssSelector( "div.hfeed" )); //获取该元素的id属性 System.out.println(e3.getAttribute( "id" )); //输出为page //(4)name:获取name='generator'的元素,当有多个时,取第一个 WebElement e4=webDriver.findElement(By.name( "generator" )); //获取该元素的content属性 System.out.println(e4.getAttribute( "content" )); //输出为WordPress 4.5.3 //(5)tagName:获取标签为script的元素,当有多个时,取第一个 WebElement e5=webDriver.findElement(By.tagName( "script" )); //获取该元素的type属性 System.out.println(e5.getAttribute( "type" )); //输出为text/javascript //(5)xpath:获取根元素下body元素下第一个div元素 WebElement e6=webDriver.findElement(By.xpath( "//body/div[1]" )); //获取该元素的id属性 System.out.println(e6.getAttribute( "id" )); //输出为page //退出浏览器 webDriver.quit(); |
4对页面元素进行操作
// 参数1为驱动类型 参数2为火狐浏览器的安装目录 浏览器下载地址http://ftp.mozilla.org/pub/firefox/releases/45.0/ System.setProperty( "webdriver.firefox.bin" , "D:/software/firefox45/firefox.exe" ); //创建一个 FirefoxDriver 的接口,用于连接 firefox WebDriver webDriver= new FirefoxDriver(); //跳转路径→进入本文章页面 webDriver.get( "https://www.baidu.com/" ); try { //休眠3秒,等待元素加载完毕,后续有讲解其他方式等待元素加载 TimeUnit.SECONDS.sleep( 3 ); //(1)输入框:根据id找到输入框 WebElement e1 =webDriver.findElement(By.id( "kw" )); //设值 e1.sendKeys( "www.like666.com" ); //得到设入的值 String text=e1.getText(); System.out.println(text); //(2)按钮:找到'百度一下'按钮 WebElement e2 =webDriver.findElement(By.id( "su" )); //点击提交 e2.click(); //还有很多其他方法 e1.clear(); //清空文本框内容,或单选项的选中项或复选框的选中项 e1.isSelected(); //判断某个单选框,复选框,下拉框是否选中 e1.isEnabled(); //判断某个单选框,复选框,下拉框是否启用 e1.submit(); //提交表单 只对表单元素type为submit的标签有效果 TimeUnit.SECONDS.sleep( 3 ); //退出浏览器 webDriver.quit(); } catch (InterruptedException e) { e.printStackTrace(); } |
5iframe处理
有 时候我们在定位一个页面元素的时候发现一直定位不了,反复检查自己写的定位器没有任何问题,代码也没有任何问题。这时你就要看一下这个页面元素是否在一个 iframe中,这可能就是找不到的原因之一。如果你在一个default content中查找一个在iframe中的元素,那肯定是找不到的。反之你在一个iframe中查找另一个iframe元素或default content中的元素,那必然也定位不到。
selenium webdriver中提供了进入一个iframe的方法:
WebDriverorg.openqa.selenium.WebDriver.TargetLocator.frame(String nameOrId)
也提供了一个返回default content的方法:
WebDriver org.openqa.selenium.WebDriver.TargetLocator.defaultContent()
这样使我们面对iframe时可以轻松应对。
以下面的html代码为例,我们看一下处现iframe。
Html代码
main.html
< html > < head > < title >FrameTest</ title > </ head > < body > < div id = "id1">this is a div!</ div > < iframe id = "frame" frameborder = "0" scrolling = "no" style = "left:0;position:absolute;" src ="frame.html"></ iframe > </ body > </ html > |
frame.html
< html > < head > < title >this is a frame!</ title > </ head > < body > < div id = "div1">this is a div,too!</ div > < label >input:</ label > < input id = "input1"></ input > </ body > </ html > |
Java代码
// 参数1为驱动类型 参数2为火狐浏览器的安装目录 浏览器下载地址http://ftp.mozilla.org/pub/firefox/releases/45.0/ System.setProperty( "webdriver.firefox.bin" , "D:/software/firefox45/firefox.exe" ); //将main.html和freme.html放入D盘根目录 WebDriver webDriver = new FirefoxDriver(); String url = "D:/main.html" ; webDriver.get(url); //在defaultcontent定位id="id1"的div webDriver.findElement(By.id( "id1" )); //此时,没有进入到id="frame"的frame中时,以下两句会报错 webDriver.findElement(By.id( "div1" )); //报错 webDriver.findElement(By.id( "input1" )); //报错 //进入id="frame"的frame中,定位id="div1"的div和id="input1"的输入框。 webDriver.switchTo().frame( "frame" ); webDriver.findElement(By.id( "div1" )); webDriver.findElement(By.id( "input1" )); //此时,没有跳出frame,如果定位defaultcontent中的元素也会报错。 webDriver.findElement(By.id( "id1" )); //报错 //跳出frame,进入defaultcontent;重新定位id="id1"的div webDriver.switchTo().defaultContent(); webDriver.findElement(By.id( "id1" )); //switch_to方法会new1个TargetLocator对象,使用该对象的frame方法可以将当前识别的”主体”移动到需要定位的frame上去。 |
6获得弹出窗口
Html代码
< span style = "white-space: normal;background-color: #ffffff;" >test.html</ span > < html > < head >< title >Test Popup Window</ title ></ head > < body > < a id = "51" href = "http://www.51.com/" target ="_blank">Let's go!</ a > </ body > </ html > |
Java代码
// 参数1为驱动类型 参数2为火狐浏览器的安装目录 浏览器下载地址http://ftp.mozilla.org/pub/firefox/releases/45.0/ System.setProperty( "webdriver.firefox.bin" , "D:/software/firefox45/firefox.exe" ); WebDriver dr = new FirefoxDriver(); String url = "D:/main.html" ; dr.get(url); dr.findElement(By.id( "51" )).click(); //得到当前窗口的句柄 String currentWindow = dr.getWindowHandle(); //得到所有窗口的句柄 Set<String> handles = dr.getWindowHandles(); Iterator<String> it = handles.iterator(); while (it.hasNext()){ if (currentWindow== it.next()) continue ; dr.switchTo().window(it.next()); } /** * 捕获或者说定位弹出窗口的关键在于获得弹出窗口的句柄。( 在上面的代码里,使用windowhandle方法来获取当前浏览器窗口的句柄,使用了windowhandles方法获取所有弹出的浏览器窗口的句柄,然后通过排除当前句柄的方法来得到新开窗口的句柄。 在获取新弹出窗口的句柄后,使用switchto.window(newwindow_handle)方法,将新窗口的句柄作为参数传入既可捕获到新窗口了。 如果想回到以前的窗口定位元素,那么再调用1次switchto.window方法,传入之前窗口的句柄既可达到目的。 */ |
7处理alert、confirm、prompt对话框
Dialogs.html
< html > < head > < title >Alert</ title > </ head > < body > < input id = "alert" value = "alert" type ="button" onclick = "alert('欢迎!请按确认继续!');"/> < input id = "confirm" value= "confirm" type = "button" onclick = "confirm('确定吗?');"/> < inputid = "prompt" value = "prompt" type = "button"onclick = "var name = prompt('请输入你的名字:','请输入 你的名字'); document.write(name) "/> </ body > </ html > |
Java
// 参数1为驱动类型 参数2为火狐浏览器的安装目录 浏览器下载地址http://ftp.mozilla.org/pub/firefox/releases/45.0/ System.setProperty( "webdriver.firefox.bin" , "D:/software/firefox45/firefox.exe" ); WebDriver dr = new FirefoxDriver(); String url = "file:///C:/Documents and Settings/gongjf/桌面/selenium_test/Dialogs.html" ;// "/Your/Path/to/main.html" dr.get(url); //点击第一个按钮,输出对话框上面的文字,然后叉掉 dr.findElement(By.id( "alert" )).click(); Alert alert = dr.switchTo().alert(); String text = alert.getText(); System.out.println(text); alert.dismiss(); //点击第二个按钮,输出对话框上面的文字,然后点击确认 dr.findElement(By.id( "confirm" )).click(); Alert confirm = dr.switchTo().alert(); String text1 = confirm.getText(); System.out.println(text1); confirm.accept(); //点击第三个按钮,输入你的名字,然后点击确认,最后 dr.findElement(By.id( "prompt" )).click(); Alert prompt = dr.switchTo().alert(); String text2 = prompt.getText(); System.out.println(text2); prompt.sendKeys( "jarvi" ); prompt.accept(); /** * getText() 得到它的文本值 accept() 相当于点击它的"确认" dismiss() 相当于点击"取消"或者叉掉对话框 sendKeys() 输入值,这个alert\confirm没有对话框就不能用了,不然会报错。 */ |
8操作cookies
// 参数1为驱动类型 参数2为火狐浏览器的安装目录 浏览器下载地址http://ftp.mozilla.org/pub/firefox/releases/45.0/ System.setProperty( "webdriver.firefox.bin" , "D:/software/firefox45/firefox.exe" ); WebDriver dr = new FirefoxDriver(); //进入百度 dr.get( "https://www.baidu.com" ); //增加一个name ="name",value="value"的cookie Cookie cookie = new Cookie( "name" , "value" ); dr.manage().addCookie(cookie); //得到当前页面下所有的cookies,并且输出它们的所在域、name、value、有效日期和路径 Set<Cookie>cookies = dr.manage().getCookies(); System.out.println(String.format( "Domain-> name -> value -> expiry -> path" )); for (Cookie c : cookies) System.out.println(String.format( "%s-> %s -> %s -> %s -> %s" , c.getDomain(),c.getName(), c.getValue(),c.getExpiry(),c.getPath())); //删除cookie有三种方法 //第一种通过cookie的name dr.manage().deleteCookieNamed( "CookieName" ); //第二种通过Cookie对象 dr.manage().deleteCookie(cookie); //第三种全部删除 dr.manage().deleteAllCookies(); |
9等待页面元素加载完成
//1线程等待 但不确定元素是否在等待结束后已经加载完成,只是预估时间 try { TimeUnit.SECONDS.sleep( 3 ); } catch (InterruptedException e) { e.printStackTrace(); } //2隐性等待,是指当要查找元素,而这个元素没有马上出现时,告诉WebDriver查询Dom一定时间。默认值是0,但是设置之后,这个时间将在WebDriver对象实例整个生命周期都起作用 System.setProperty( "webdriver.firefox.bin" , "D:/software/firefox45/firefox.ex" ); WebDriver dr = new FirefoxDriver(); //设置10秒 dr.manage().timeouts().implicitlyWait( 10 ,TimeUnit.SECONDS); |
10利用selenium-webdriver截图
// 参数1为驱动类型 参数2为火狐浏览器的安装目录 浏览器下载地址http://ftp.mozilla.org/pub/firefox/releases/45.0/
System.setProperty(
"webdriver.firefox.bin"
,
"D:/software/firefox45/firefox.exe"
);
//创建一个 FirefoxDriver 的接口,用于连接 firefox
WebDriver webDriver=
new
FirefoxDriver();
//跳转路径→进入淘宝页面
webDriver.get(
"https://www.taobao.com/"
);
try
{
TimeUnit.SECONDS.sleep(
5
);
//下面代码是得到截图并保存在D盘下
File screenShotFile = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(screenShotFile,
new
File(
"D:/test.png"
));
webDriver.quit();
}
catch
(InterruptedException e) {
e.printStackTrace();
}
catch
(IOException e) {
e.printStackTrace();
}