简介
Selenium是一个用于Web应用程序测试的工具, 支持各种浏览器, 一般都是用作自动化测试的, 但是如果配合上代理, 可以实现爬虫的效果。
环境搭建
selenium 成功运行, 必须要有 webdriver + 浏览器, 并且2者的版本号要一致才能使用, 安装chrome浏览器, 把webdriver解压到磁盘中。
可以直接使用下面的
https://soscdn.lanzoui.com/b015e2c2h
密码:8ot9
如何使用
maven
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
简单示例
实现点击下面的a标签
- 页面-a.html
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>a标签</title>
</head>
<body>
<a onclick="javascript:(console.log('a'))">点我</a>
</body>
</html>
- 代码
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class Taga {
public static void main(String[] args) throws Exception {
// 后面的目录就是上面解压的drvier的目录
System.setProperty("webdriver.chrome.driver", "D:\\xiaodoubi\\selemium\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
// 打开网页(把页面放到nginx中)
driver.get("http://127.0.0.1/a.html");
// 休眠的时候, 按F12, 打开浏览器控制台-console
Thread.sleep(5000);
// 选择
for (int i = 0; i < 4; i++) {
driver.findElement(By.tagName("a")).click();
Thread.sleep(2000);
}
// 关闭浏览器
driver.close();
}
}
具体api讲解
WebDriver
方法 | 含义 | 备注 |
---|---|---|
get(String url) | 打开url | |
getCurrentUrl() | 获取当前url | |
getTitle() | 获取标题 | |
findElements(By by) | 获取元素 | |
findElement(By by) | 获取元素 | |
getPageSource() | 获取源码 | |
close() | 关闭 | Close the current window, quitting the browser if it's the last window currently open. |
quit() | 退出 | Quits this driver, closing every associated window. |
getWindowHandles() | 获取浏览器窗口名称 | |
getWindowHandle() | 获取浏览器窗口名称 | |
switchTo() | 切换 | |
navigate() | 导航条 | 返回, 下一步, 刷新, 跳到其他链接等等 |
manage() | 浏览器的控制 | cookie的操作, 窗口大小的控制等等 |
- 代码
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class WebDriverTest {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:\\liumq\\selemium\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
// 打开网页(把页面放到nginx中)
driver.get("http://www.baidu.com/");
// 获取当前url
System.out.println("---------------------------------------------");
System.out.println(driver.getCurrentUrl());
// 获取标题
System.out.println("---------------------------------------------");
System.out.println(driver.getTitle());
// 获取元素
System.out.println("---------------------------------------------");
WebElement input = driver.findElement(By.id("su"));
System.out.println(input.getAttribute("value"));
// 获取元素
System.out.println("---------------------------------------------");
List<WebElement> inputs = driver.findElements(By.tagName("input"));
for (WebElement webElement : inputs) {
System.out.println(webElement.getAttribute("value"));
break;
}
// 获取源代码
System.out.println("---------------------------------------------");
// System.out.println(driver.getPageSource());
// 获取窗口
// 这边模拟了一次搜索点击(后面会细讲)
System.out.println("---------------------------------------------");
driver.findElement(By.id("kw")).sendKeys("selenium");
driver.findElement(By.id("su")).click();
for (int i = 1; i < 5; i++) {
driver.findElement(By.id(String.valueOf(i))).findElement(By.tagName("a")).click();
}
String windowHandle = driver.getWindowHandle();
System.out.println(windowHandle);
driver.getWindowHandles().forEach(System.out::println);
// 窗口切换
driver.getWindowHandles().forEach(s->{
driver.switchTo().window(s);
try {
Thread.sleep(3000);
} catch (Exception e) {
}
});
// 导航
driver.navigate().to("http://360.cn/");
// 浏览器的控制
driver.manage().window().maximize();
// 上面点开了多个窗口, 就明白了close和quit的区别
// driver.close();
driver.quit();
}
}
控件的定位
推荐使用css选择器, 对于有爬虫开发经验的来说, 太方便了
By.cssSelector("")
主要控件的操作
input-输入框
radio-单选框
checkbox-复选框
Select-下拉框
键盘输入
鼠标点击
- html
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>下拉框</title>
</head>
<body>
<div>
<p>输入框</p>
<input type="text" id="ipt"></input>
</div>
<div>
<p>单选框</p>
<input type="radio" checked value="北京" name="city>" />北京
<input type="radio" value="上海" name="city>" />上海
<input type="radio" value="广州" name="city>" />广州
<input type="radio" value="深圳" name="city>" />深圳
</div>
<div>
<p>多选项</p>
<input type="checkbox" value="羽毛球" name="aihao>" />羽毛球
<input type="checkbox" value="乒乓球" name="aihao>" />乒乓球
<input type="checkbox" checked value="足球" name="aihao>" />足球
<input type="checkbox" value="篮球" name="aihao>" />篮球
</div>
<div>
<p>下拉框</p>
<select class="ppaf-select">
<option value="AUD">AUD</option>
<option value="BRL">BRL</option>
<option value="CAD">CAD</option>
<option value="CHF">CHF</option>
<option value="CZK">CZK</option>
<option value="DKK">DKK</option>
<option value="EUR">EUR</option>
<option value="GBP">GBP</option>
<option value="HKD">HKD</option>
<option value="HUF">HUF</option>
<option value="ILS">ILS</option>
<option value="JPY">JPY</option>
<option value="MXN">MXN</option>
<option value="MYR">MYR</option>
<option value="NOK">NOK</option>
<option value="NZD">NZD</option>
<option value="PHP">PHP</option>
<option value="PLN">PLN</option>
<option value="RUB">RUB</option>
<option value="SEK">SEK</option>
<option value="SGD">SGD</option>
<option value="THB">THB</option>
<option value="TRY">TRY</option>
<option value="TWD">TWD</option>
<option value="USD">USD</option>
</select>
</div>
<div>
<button id="btn" onclick="javascript:(alert('点我了'))">点我</button>
</div>
</body>
</html>
- 代码
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;
public class TagTest {
public static void main(String[] args) throws AWTException {
System.setProperty("webdriver.chrome.driver", "D:\\liumq\\selemium\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
// 打开网页(把页面放到nginx中)
driver.get("http://172.18.254.33:7766/html/tags.html");
// 输入框
driver.findElement(By.id("ipt")).sendKeys("小逗比");
// 单选框
List<WebElement> radios = driver.findElements(By.cssSelector("input[type=radio]"));
for (WebElement webElement : radios) {
String value = webElement.getAttribute("value");
if (value.equals("上海")) {
webElement.click();
}
}
// 复选框 取消足球, 选择乒乓球, 羽毛球
List<WebElement> checkbox = driver.findElements(By.cssSelector("input[type=checkbox]"));
for (WebElement webElement : checkbox) {
String value = webElement.getAttribute("value");
System.out.println(value);
switch (value) {
case "足球":
if (webElement.isSelected()) {
webElement.click();
}
break;
case "羽毛球":
case "乒乓球":
if (!webElement.isSelected()) {
System.out.println(value);
webElement.click();
}
break;
default:
break;
}
}
// 下拉框 选择PHP
Select select = new Select(driver.findElement(By.cssSelector(".ppaf-select")));
select.selectByValue("PHP");
// 按键输入
WebElement findElement = driver.findElement(By.id("ipt"));
findElement.click();
// method1: actions 推荐
Actions actions = new Actions(driver);
actions.sendKeys("a").keyDown(Keys.SHIFT).sendKeys("a").keyUp(Keys.SHIFT).build().perform();
// method2: robot
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_B);
robot.keyRelease(KeyEvent.VK_B);
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_B);
robot.keyRelease(KeyEvent.VK_B);
robot.keyRelease(KeyEvent.VK_SHIFT);
// 鼠标点击
actions.moveToElement(By.id("btn").findElement(driver)).click().build().perform();
}
}
启动参数配置
ChromeDriver
上面我们使用的selenium接口中的WebDriver, 如果我们使用具体对应的浏览器的Driver, 我们发现有了好多花式操作。(简单举例说明)
- 运行js脚本(神器)
- 操作LocalStorage
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:\\liumq\\selemium\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
// 打开网页(把页面放到nginx中)
driver.get("http://172.18.254.33:7766/html/tags.html");
if(driver instanceof ChromeDriver){
ChromeDriver cdriver = (ChromeDriver)driver;
// 运行js脚本, 这个是神器(一些非常不能实现的都可以使用js脚本来实现)
cdriver.executeScript("alert('aa')", "");
// 获取以及设置存储数据
LocalStorage localStorage = cdriver.getLocalStorage();
localStorage.setItem("a", "a");
System.out.println(localStorage.getItem("a"));
}
}
超时设置
一旦由于网络原因,或者其他原因, 页面长时间未加载出来, 我们发现就会报控件没有找到错误, 我们需要更好的解决此问题,让程序加载出来
- 方法1
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
- 方法2
WebDriverWait webDriverWait = new WebDriverWait(driver, 20);
WebElement element = webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.id("")));
- 方法3
我们可以通过try, 不过异常实现一直重试, 就是我们可以直接控制重试时间和次数,
class Continue{
public static void find(Runnable call) {
// 进入我的首页
while (true) {
try {
Thread.sleep(1000);
call.run();
break;
} catch (Exception e) {
System.out.println("未找到");
}
}
}
}
// 选择
Continue.run(() -> {
Select select = new Select(driver.findElement(By.cssSelector(".ppaf-select")));
select.selectByValue("PHP");
});