文章目录
参考文章:https://blog.csdn.net/qq_22003641/article/details/79137327?spm=1001.2014.3001.5506
前言
使用selenium进行爬虫,需要下载相关浏览器的驱动程序,和添加selenium相关的jar包。
浏览器驱动程序地址:
- Firefox浏览器驱动:Firefox
- Chrome浏览器驱动:chrome淘宝镜像
- Edge浏览器驱动:edge
selenium相关依赖:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.4.0</version>
</dependency>
jar包下载地址:https://mvnrepository.com/
一、Selenium是什么?
Selenium是一个用于web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。Selenium完全开源,对商业用户也没有任何限制,支持分布式,拥有成熟的社区与学习文档。使用Selenium实现爬虫最大的好处在于能够模拟一个用户正常访问页面,网站后台不容易检测出来,而且使用简单,可以使用java或python等多种编程语言编写用例脚本。
二、Selenium常见的API
1.Selenium定位的方法
Selenium提供了8种定位方式,这些方式在Java中所对应的方法如下:
- id-------------------------------------------------------------findElement(By.id())
- name--------------------------------------------------------findElement(By.name())
- class name------------------------------------------------findElement(By.className())
- tag name--------------------------------------------------findElement(By.tagName())
- link text----------------------------------------------------findElement(By.linkText())
- partial link text-------------------------------------------findElement(By.partialLinkText())
- xpath-------------------------------------------------------findElement(By.xpath())
- css selector----------------------------------------------findElement(By.cssSelector())
具体使用例子:
<html>
<head></head>
<body link="#0000cc">
<a id="result_logo" href="/" onmousedown="return c({
'fm':'tab','tab':'logo'})">
<form id="form" class="fm" name="f" action="/s">
<span class="soutu-btn"></span>
<input id="kw" class="s_ipt" name="wd" value="" maxlength="255" autocomplete="off">
</form>
<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>
</body>
</html>
driver.findElement(By.id("kw"));//通过id定位的方式定位到input标签上面。
driver.findElement(By.name("wd"));//通过name定位方式定位到input标签上面。
driver.findElement(By.className("s_ipt"));//通过class name定位到input标签上面。
driver.findElement(By.tagName("input"))//通过tag name定位到input标签上面。
driver.findElement(By.xpath("//*[@id='kw']"));//通过xpath定位到input标签上面。
driver.findElement(By.cssSelector("#kw");//通过css定位到input标签上面。
driver.findElement(By.linkText("新闻");//通过link text定位到a标签上面。
driver.findElement(By.partialLinkText("新");//通过partialLink text定位到a标签上面。
提示:鼠标对准元素右键 > 检查 > 对准标签右键 > 点击copy,即可直接复制通过xpath或css等定位方式的路径。
2.控制浏览器窗口大小
- maximize() 设置浏览器最大化
- setSize() 设置浏览器宽高
例子:讲浏览器窗口的大小设置成(500*800)
driver.manage().window().setSize(new Dimension(480, 800));
3.控制浏览器后退、前进
在使用浏览器浏览网页时,浏览器提供了后退和前进按钮,可以方便地在浏览过的网页之间切换,WebDriver也提供了对应的back()和forward()方法来模拟后退和前进按钮。下面通过例子来演示这两个方法的使用。
- back() 模拟浏览器后退按钮
- forward() 模拟浏览器前进按钮
driver.navigate().back();
driver.navigate().forward();
4.刷新页面
有时候需要手动刷新(F5) 页面。
- refresh() 刷新页面(F5)
driver.navigate().refresh();
三、WebDriver常用方法
方法 | 含义 |
---|---|
clear() | 清除文本 |
sendKeys(*value) | 模拟按键输入 |
click() | 单击元素 |
submit() | 提交表单 |
getSize() | 返回元素的尺寸 |
getText() | 获取元素的文本 |
getAttribute(name) | 获得属性值 |
isDisplayed() | 设置该元素是否用户可见 |
四、模拟鼠标的操作
方法 | 含义 |
---|---|
contextClick() | 右击 |
clickAndHold() | 鼠标点击并控制 |
doubleClick() | 双击 |
dragAndDrop() | 拖动 |
release() | 释放鼠标 |
perform() | 执行所有Actions中存储的行为 |
五、模拟键盘操作
Keys()类提供了键盘上几乎所有按键的方法。 前面了解到, sendKeys()方法可以用来模拟键盘输入, 除此之 外, 我们还可以用它来输入键盘上的按键, 甚至是组合键, 如 Ctrl+A、 Ctrl+C 等。
例子:
input.sendKeys(Keys.SPACE);
input.sendKeys("教程");
Thread.sleep(2000);
input.sendKeys(Keys.CONTROL,"a");
Thread.sleep(2000);
六、获取断言信息
方法 | 含义 |
---|---|
getTitle() | 用于获得当前页面的title |
getCurrentUrl() | 用户获得当前页面的URL |
getText() | 获取页面文本信息 |
七、设置元素等待
WebDriver提供了两种类型的等待:显式等待和隐式等待。
显示等待
WebDriverWait类是由WebDirver提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。具体格式如下:
WebDriverWait(driver, 10, 1)
driver: 浏览器驱动。 10: 最长超时时间, 默认以秒为单位。 1: 检测的的间隔(步长) 时间, 默认为 0.5s。
public static void main(String[]args) throws InterruptedException {
WebDriver driver = new ChromeDriver();
driver.get("https://www.baidu.com");
//显式等待, 针对某个元素等待
WebDriverWait wait = new WebDriverWait(driver,10,1);
wait.until(new ExpectedCondition<WebElement>(){
@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就会抛出异常。 |
八、多表单切换
- driver.switchTo().frame(xf),xf为另一个表单的元素。
WebElement xf = driver.findElement(By.xpath("//*[@id='loginDiv']/iframe"));
driver.switchTo().frame(xf);
九、多窗口切换
- switchTo().window()
- getWindowHandle(): 获得当前窗口句柄。
- getWindowHandles(): 返回的所有窗口的句柄到当前会话。
- switchTo().window():用于切换到相应的窗口,与上一节的switchTo().frame()类似,前者用于不同窗口的切换, 后者用于不同表单之间的切换。
driver.switchTo().window(handle);
十、下拉框选择
<select id="nr" name="NR">
<option value="10" selected>每页显示 10 条</option>
<option value="20">每页显示 20 条</option>
<option value="50">每页显示 50 条</option>
<select>
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new ChromeDriver();
driver.get("https://www.baidu.com");
driver.findElement(By.linkText("设置")).click();
driver.findElement(By.linkText("搜索设置")).click();
Thread.sleep(2000);
//<select>标签的下拉框选择
WebElement el = driver.findElement(By.xpath("//select"));
Select sel = new Select(el);
sel.selectByValue("20");
Thread.sleep(2000);
driver.quit();
}
十一、警告框处理
- getText(): 返回 alert/confirm/prompt 中的文字信息。
- accept(): 接受现有警告框。
- dismiss(): 解散现有警告框。
- sendKeys(keysToSend): 发送文本至警告框。
- keysToSend:将文本发送至警告框。
public static void main(String[] args) throws InterruptedException {
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();
}
十二、浏览器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 信息。
public static void main(String[] args){
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
Set<Cookie> coo = driver.manage().getCookies();
System.out.println(coo);
//删除所有 cookie
//driver.manage().deleteAllCookies();
driver.quit();
}
十三、调用JavaScript代码
虽然WebDriver提供了操作浏览器的前进和后退方法,但对于浏览器滚动条并没有提供相应的操作方法。在这种情况下,就可以借助JavaScript来控制浏览器的滚动条。WebDriver提供了executeScript()方法来执行JavaScript代码。
public static void main(String[] args) throws InterruptedException{
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();
}
注意事项
- 下载浏览器驱动程序时,尽量与自己电脑的浏览器版本一致或相近。
其实我也不知道为什么要这样,理论上来说下载的驱动程序应该不与电脑本身的浏览器有联系,但之前在爬虫时遇到一些问题,上网搜一下,基本上都是说驱动程序版本不一致。为了快速的实现功能,还是下载对应的版本驱动程序吧,避免后面出现问题。