网页自动化工具 Selenium

大概五六年前接触过 Selenium 了,当时使用 Selenium 结合 jUnit 写过一套自动化测试与报警系统,但是效果不太好(和网络、数据各方面都有关系),而且仅仅几十个用例虽然不然,但写的超级心烦,每次都要找 xpath 一个操作写好多行 java代码。

现在由于有差不多的需求,使我回想到了它。所以拿出来再重温下,当然时代变了,现在更流行的 phantomjs 也下载试用了一下,由于几个不能忍的Bug档住了我的去路,所以还是先保持一下观望的态度了。再者 Selenium 是 Thoughtwork 公司出品,个人比较相信他们的水平。

Selenium 这个技术确实很有趣,上次使用是做一套自动化测试的工具,现在用它来做一些网页插件,它也可也做爬虫,一般的爬虫对 javascript 产生的内容,ajax 等没有读取能力,这时候 headless 爬虫就有用武之地了。

简单使用

引入依赖

1
2
3
4
5
6
7
8
9
10
11
 <dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.0.1</version>
</dependency>

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.0.1</version>
</dependency>

启动服务端

1
2
3
public static void main(String[] args) throws Exception {
org.openqa.grid.selenium.GridLauncherV3.main(new String[]{});
}

下载ChromeDriver

下载地址: https://sites.google.com/a/chromium.org/chromedriver/downloads
下载后,放在chrome.exe相同的目录,不放在那应该也可以,所以我放在了C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe

编写脚本

很久没有用selenium了,现在惊奇发现selenium已经支持了cssSelector,这样去找元素就简单太多了,再也不用像以前那样搞xPath了.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 public static void main(String[] args) throws InterruptedException {
//设置chromedriver的路径
System.setProperty("webdriver.chrome.driver","C:\\Program Files (x86)\\Google\\Chrome\\Application\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.baidu.com/");
Thread.sleep(5000);
//根据Name找到输入框
WebElement keyword = driver.findElement(By.name("wd"));
//输入关键字
keyword.sendKeys("http://www.xdnote.com");
Thread.sleep(3000);
//点击搜索按钮
WebElement search = driver.findElement(By.cssSelector(".s_btn_wr .s_btn"));
search.click();
Thread.sleep(3000);
//退出
driver.quit();
}

高级使用

上面一段代码展示了基本功能,实际上就输入,点击两个动作,已经占据了我们浏览网页行为的一大半了.

以下介绍一些个人用到的实用的网页功能

  1. 比如很多登录,是通过IFrame嵌入在网页里面的,可以通过driver.switchTo().frame(iframe) 去切换正在使用的driver.

    1
    2
    3
    4
    5
    6
    7
    //如果能够找到iframe
    WebElement iframe = driver.findElement(By.id("iframe"))
    driver.switchTo().frame(iframe);
    //切换到父级iframe
    driver.switchTo().parentFrame();
    //默认切换,如果一个页面只有一个iframe时,直接用这个去切换吧,再调一次就切回来了.
    driver.switchTo().defaultContent()
  2. Element集成了一个点击click事件,有时候,需要其它鼠标事件时,可以通过Action来构造

    1
    2
    3
    Actions action = new Actions(driver);
    //鼠标移动到了element上面了.
    action.moveToElement(element).build().perform();
  3. 篡改页面的Cookie,这个…

1
2
3
4
WebDriver.Options options = driver.manage();
options.getCookies();
options.getCookieNamed(".auth");
options.deleteCookieNamed(".auth");
  1. 截图,很实用的功能。

    1
    2
    File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File("D:\\Screen\\screenshot.png"));
  2. 运行JavaScript, 强大但可能并不太实用,除非目的特殊了。

    1
    2
    3
    4
    5
    JavascriptExecutor js;
    if (driver instanceof JavascriptExecutor) {
    js = (JavascriptExecutor)driver;
    js.executeScript("return document.getElementById('someId');");
    }

小结

其实经过了一些研究,发现3.0的变动很大,比之前的2.x系列即强大又好用很多,api基本通过名字都能理解用途。

个人不是太喜欢用Java代码去写这种东西,但写久了还是觉得能体会到一点Java的好处的。比如之前可以结合jUnit 测试(个人觉得jUnit是最好的测试框架(可以加入各种插件),目前的JavaScript都很难比上它)。