文档章节

模拟浏览器的神器 - HtmlUnit

杨尚川
 杨尚川
发布于 2014/04/04 03:00
字数 684
阅读 3115
收藏 13

随着Web的发展,RIA越来越多,JavaScript和Complex AJAX Libraries给网络爬虫带来了极大的挑战,解析页面的时候需要模拟浏览器执行JavaScript才能获得需要的文本内容。

 

好在有一个Java开源项目HtmlUnit,它能模拟Firefox、IE、Chrome等浏览器,不但可以用来测试Web应用,还可以用来解析包含JS的页面以提取信息。

 

下面看看HtmlUnit的效果如何:

 

首先,建立一个maven工程,引入junit依赖和HtmlUnit依赖:

 

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.8.2</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>net.sourceforge.htmlunit</groupId>
	<artifactId>htmlunit</artifactId>
	<version>2.14</version>
</dependency>

 

 

其次,写一个junit单元测试来使用HtmlUnit提取页面信息:

 

/**
 * 使用HtmlUnit模拟浏览器执行JS来获取网页内容
 * @author 杨尚川
 */
public class HtmlUnitTest {
    @Test
    public void homePage() throws Exception {
        final WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_11);
        final HtmlPage page = webClient.getPage("http://yangshangchuan.iteye.com");
        Assert.assertEquals("杨尚川的博客 - ITeye技术网站", page.getTitleText());
        final String pageAsXml = page.asXml();
        Assert.assertTrue(pageAsXml.contains("杨尚川,系统架构设计师,系统分析师,2013年度优秀开源项目APDPlat发起人,资深Nutch搜索引擎专家。多年专业的软件研发经验,从事过管理信息系统(MIS)开发、移动智能终端(Win CE、Android、Java ME)开发、搜索引擎(nutch、lucene、solr、elasticsearch)开发、大数据分析处理(Hadoop、Hbase、Pig、Hive)等工作。目前为独立咨询顾问,专注于大数据、搜索引擎等相关技术,为客户提供Nutch、Lucene、Hadoop、Solr、ElasticSearch、HBase、Pig、Hive、Gora等框架的解决方案、技术支持、技术咨询以及培训等服务。"));
        final String pageAsText = page.asText();
        Assert.assertTrue(pageAsText.contains("[置顶] 国内首套免费的《Nutch相关框架视频教程》(1-20)"));
        webClient.closeAllWindows();
    }
    @Test
    public void homePage_Firefox() throws Exception {
        final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24);
        final HtmlPage page = webClient.getPage("http://yangshangchuan.iteye.com");        
        Assert.assertEquals("杨尚川的博客 - ITeye技术网站", page.getTitleText());
        webClient.closeAllWindows();
    }
    @Test
    public void getElements() throws Exception {
        final WebClient webClient = new WebClient(BrowserVersion.CHROME);
        final HtmlPage page = webClient.getPage("http://yangshangchuan.iteye.com");
        final HtmlDivision div = page.getHtmlElementById("blog_actions");
        //获取子元素
        Iterator<DomElement> iter = div.getChildElements().iterator();
        while(iter.hasNext()){
            System.out.println(iter.next().getTextContent());
        }
        //获取所有输出链接
        for(HtmlAnchor anchor : page.getAnchors()){
            System.out.println(anchor.getTextContent()+" : "+anchor.getAttribute("href"));
        }
        webClient.closeAllWindows();
    }
    @Test
    public void xpath() throws Exception {
        final WebClient webClient = new WebClient();
        final HtmlPage page = webClient.getPage("http://yangshangchuan.iteye.com");
        //获取所有博文标题
        final List<HtmlAnchor> titles = (List<HtmlAnchor>)page.getByXPath("/html/body/div[2]/div[2]/div/div[16]/div/h3/a");
        for(HtmlAnchor title : titles){
            System.out.println(title.getTextContent()+" : "+title.getAttribute("href"));
        }
        //获取博主信息
        final HtmlDivision div = (HtmlDivision) page.getByXPath("//div[@id='blog_owner_name']").get(0);
        System.out.println(div.getTextContent());
        webClient.closeAllWindows();
    }
    @Test
    public void submittingForm() throws Exception {
        final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24);
        final HtmlPage page = webClient.getPage("http://www.oschina.net");
        // Form没有name和id属性
        final HtmlForm form = page.getForms().get(0);
        final HtmlTextInput textField = form.getInputByName("q");
        final HtmlButton button = form.getButtonByName("");
        textField.setValueAttribute("APDPlat");
        final HtmlPage resultPage = button.click();
        final String pageAsText = resultPage.asText();
        Assert.assertTrue(pageAsText.contains("找到约"));
        Assert.assertTrue(pageAsText.contains("条结果"));        
        webClient.closeAllWindows();
    }
}

 

 

最后,我们运行单元测试, 全部通过测试! 

 



 

© 著作权归作者所有

杨尚川

杨尚川

粉丝 1103
博文 220
码字总数 1624053
作品 12
东城
架构师
私信 提问
加载中

评论(6)

Maven4
Maven4
如果所有的网页都需要认证的话就比较难了。。。
well
well
不知道大规模抓取上效率如何?如果应用到分布式爬取上,js css 重复获取带来的性能怎样?
Linesh
Linesh

引用来自“CodeCleaner”的评论

你就说这代码怎么看吧

引用来自“杨尚川”的评论

怎么了?你用手机看不了吗?
抱歉,现在看到了。嗯是关于HtmlUtil的代码,感谢博主的分享
杨尚川
杨尚川 博主

引用来自“CodeCleaner”的评论

你就说这代码怎么看吧
怎么了?你用手机看不了吗?
Linesh
Linesh
你就说这代码怎么看吧
maiyang
maiyang
收藏
HtmlUnit 网络爬虫 菜鸟的学习笔记(一)

什么是HtmlUnit HtmlUnit是一个开源的浏览器模拟工具,可以方便我们模拟浏览器的行为,例如打开网页,提交表单等,这样我们可以用他来爬网页 官网下载:http://htmlunit.sourceforge.net/ ja...

木有芒果
2015/08/31
502
0
HtmlUnit 2.6发布

HtmlUnit 是 JUnit 的扩展测试框架之一。HtmlUnit 将返回文档模拟成 HTML,这样您便可以直接处理这些文档了。HtmlUnit 使用例如 table、form 等标识符将测试文档作为 HTML 来处理。它同样需要...

红薯
2009/09/07
3.3K
0
HtmlUnit 2.8 发布,Java的Web单元测试

HtmlUnit 是 JUnit 的扩展测试框架之一。HtmlUnit 将返回文档模拟成 HTML,这样您便可以直接处理这些文档了。HtmlUnit 使用例如 table、form 等标识符将测试文档作为 HTML 来处理。它同样需要...

红薯
2010/08/12
2.2K
0
Nutch-Htmlunit 1.8 发布:基于Apache Nutch和Htmlunit的扩展实现AJAX页面爬虫抓取解析插件

之前提供了一个版本,是直接把plugin形式的源码放到代码库,后来发现有不少人反馈说自己集成到apache nutch中编译或运行,遇到这那的问题。因此这次干脆基于Apache Nutch 1.8源码工程,把所有...

EntDIY
2014/08/08
3.8K
11
基于Apache Nutch和Htmlunit的扩展实现AJAX页面爬虫抓取解析插件

之前提供了一个版本,是直接把plugin形式的源码放到代码库,后来发现有不少人反馈说自己集成到apache nutch中编译或运行,遇到这那的问题。因此这次干脆基于Apache Nutch 1.8源码工程,把所有...

EntDIY
2014/08/07
2.8K
4

没有更多内容

加载失败,请刷新页面

加载更多

Centos7 python2.7和yum完全卸载及重装

                                     完全重装python和yum 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 1、删除现有...

roockee
29分钟前
5
0
【软件工程】绪论,深入浅出理解软件工程

软件和软件工程 什么是软件工程 软件工程是贯穿整个软件生命周期的工程学和方法论及其使用的工具(我说的) 软件工程要解决那些问题 软件的研发周期过长 软件开发成本居高不下 软件在交付之前...

丌官尚雄
36分钟前
7
0
无回路有向图的拓扑排序

因公司业务需要,在表单中每个字段都会配置自动计算,但自动计算公式中会引用到其他字段中的值。所以希望可以根据计算公式,优先计算引用的公式。所以最终使用了无回路有向图的扩扑排序来实现...

兜兜毛毛
今天
7
0
如何抢占云栖大会C位?史上最强强强攻略来了

点击观看视频: APSARA云栖大会开发者情怀 原文链接 本文为云栖社区原创内容,未经允许不得转载。

阿里云官方博客
今天
6
0
Kubernetes 从懵圈到熟练:集群服务的三个要点和一种实现

作者 | 声东 阿里云售后技术专家 文章来源:Docker,点击查看原文。 以我的经验来讲,理解 Kubernetes 集群服务的概念,是比较不容易的一件事情。尤其是当我们基于似是而非的理解,去排查服务...

阿里巴巴云原生
今天
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部