网页自动化工具 Selenium

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

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

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

简单使用

引入依赖

 <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>

启动服务端

    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了.

    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.

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

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

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

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

    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都很难比上它)。