文档章节

模拟浏览器的神器 - HtmlUnit

杨尚川
 杨尚川
发布于 2014/04/04 03:00
字数 684
阅读 2654
收藏 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();
    }
}

 

 

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

 



 

© 著作权归作者所有

共有 人打赏支持
杨尚川

杨尚川

粉丝 1093
博文 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
0
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.7K
11
基于Apache Nutch和Htmlunit的扩展实现AJAX页面爬虫抓取解析插件

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

EntDIY
2014/08/07
2.7K
4

没有更多内容

加载失败,请刷新页面

加载更多

崛起于Springboot2.X之通讯WebSocket(40)

技术简介:Springboot2.0.3+freemaker+websocket 1、添加pom依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-bo......

木九天
12分钟前
0
0
Java常用四大线程池用法以及ThreadPoolExecutor详解

为什么用线程池? 1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处-理效率 2.线程并发数量过多,抢占系统资源从而导致阻塞 3.对线程进行一些简单的管理 在Java中...

孟飞阳
14分钟前
0
0
Netty+Websocket 实现一个简易聊天室

后台代码 /** * 服务端 */public class ChatServer {public static void main(String[] args) throws Exception {int port=8080; //服务端默认端口new ChatServer().bind...

这很耳东先生
16分钟前
1
0
一个本科学生对Linux的认知

我是一名大三的普通一本大学的软件工程的一名学生,学校开设了一些关于系统开发的课程,纸上得来终觉浅,学校的课程课时较短,想要在56个课时之内学会一些公司需要的技能,无疑是纸上谈兵,一...

linuxprobe16
18分钟前
0
0
如何选择开源许可证?

如何为代码选择开源许可证,这是一个问题。 世界上的开源许可证,大概有上百种。很少有人搞得清楚它们的区别。即使在最流行的六种----GPL、BSD、MIT、Mozilla、Apache和LGPL----之中做选择,...

吴伟祥
19分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部