文档章节

HtmlUnit,想说爱你并不容易

毛三胖
 毛三胖
发布于 2017/03/16 11:18
字数 1269
阅读 158
收藏 0

1.HtmlUnit简要介绍

HtmlUnit是一款java的无界面浏览器程序库。它模拟HTML文档,并提供相应的API,允许您调用页面,填写表单,点击链接等操作,就像您在“正常”浏览器中做的一样。它有相当不错的JavaScript支持(还在不断改进),甚至能够处理相当复杂的AJAX库,模拟Chrome,Firefox或Internet Explorer取决于使用的配置。它通常用于测试目的或从网站检索信息。

HtmlUnit不是一个通用的单元测试框架。它是一种模拟浏览器以用于测试目的的方法,并且旨在用于另一个测试框架(如JUnit或TestNG)中。有关简介,请参阅文档“HtmlUnit入门”。HtmlUnit用作不同的开源工具,如Canoo WebTest,JWebUnit,WebDriver,JSFUnit,WETATOR,Celerity,Spring MVC Test HtmlUnit作为底层的“浏览器”。

HtmlUnit最初由Gargoyle Software的Mike Bowler编写,并根据Apache 2许可证发布。从那时起,它已经收到了许多来自其他开发商的贡献,今天也会得到他们的帮助。

几年前在做一个购物网站的数据抓取工作中,偶然的机会邂逅了HtmlUnit了。记得当时怎么也捉取不到页面上的价格数据,而httpfox也追踪不到价格数据的URL,正当我一愁莫展的时个,HtmlUnit出现并帮我解决了问题。所以今天我要说声谢谢,也将HtmlUnit推荐给大家。

官网地址:htmlunit@sourceforge

2.HtmlUnit动一小手

下载所有Jar文件到类路径中,所有Jar文件可在地址:HtmlUnitJars 下载到。或者利用Maven依赖,如下:

<dependency>
    <groupId>net.sourceforge.htmlunit</groupId>
    <artifactId>htmlunit</artifactId>
    <version>2.25</version>
</dependency>

下面以某购物网站列表页为例,做一个基本的数据捉取的例子,输入的条件为网站的列表页URL地址,输出的结果为该页面所有产品的名称,价格和评论数并以//做为分隔。不包括推广产品。

例如输入:https://list.jd.com/list.html?cat=9987,653,655

结果输出(多条):

魅族 魅蓝metal 16GB 灰色 电信4G手机 双卡双待//¥699.00 ¥699.00//已有5.2万+人评价
OPPO R9s 全网通4G+64G 双卡双待手机 玫瑰金//¥2799.00 ¥2799.00//已有8.6万+人评价

示例程序代码:

package com.du42.htmlunit;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import java.util.List;

/**
 * Created by iFat3 on 2017/3/15 42du.cn.
 */
public class JDListTools {

    public static void getItems() throws Exception {
        WebClient webClient = new WebClient(BrowserVersion.BEST_SUPPORTED);
        webClient.getOptions().setCssEnabled(false);
        webClient.getOptions().setJavaScriptEnabled(true);
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        webClient.waitForBackgroundJavaScript(600*1000);
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
        HtmlPage page = webClient.getPage("https://list.jd.com/list.html?cat=9987,653,655");
        List<HtmlDivision> divs = (List) page.getByXPath("//div[@id='plist']//ul//li[@class='gl-item']//div[@class='gl-i-wrap j-sku-item']");
        for(HtmlDivision  div :divs) {
            DomNodeList<DomNode> childs = div.getChildNodes();
            String name = "";
            String price = "";
            String comments = "";
            for(DomNode dn : childs) {
                NamedNodeMap map = dn.getAttributes();
                Node node = map.getNamedItem("class");
                if(node != null) {
                    String value = node.getNodeValue();
                    if(value.contains("p-name")) {
                        name = dn.asText();
                    } else if(value.contains("p-price")) {
                        price = dn.asText();
                    } else if(value.contains("p-commit")) {
                        comments = dn.asText();
                    }
                }
            }
            System.out.println(name+"//"+price+"//"+comments);
        }
    }

    public static void main(String[] args) throws Exception {
        getItems();
    }
}

如程序不能取得数据,请调整选择器部分代码。

3.HtmlUnit特性

  • 支持HTTP和HTTPS协议

  • 支持Cookie

  • 能够指定来自服务器的失败响应是否应该抛出异常,或者应该做为适当类型的页面返回(基于内容类型)

  • 支持提交方法POST和GET(以及HEAD,DELETE,...)

  •  能够定制发送到服务器的请求标头

  • 支持HTML响应

    • HTML页面的封装容易访问其中包含的所有信息

    • 支持提交表单

    • 支持点击链接

    • 支持步行HTML文档的DOM模型

  • 代理服务器支持

  • 支持基本和NTLM身份验证

  • 优秀的JavaScript支持

4.HtmlUnit总结

HtmlUnit的无界面浏览器的核心思想非常好,能执行JavaScript,使其在精神上领先一步。在做数据捉取方面,不用再去做复杂的调用跟踪,AJAX解析等,只要连接页面,等待后台JavaScript执行完毕即可得到想要的Dom文档了。

而在实际的应用中,还是有很多不尽如人意的地方,其一就是对JavaScript执行并不完美,并不能总是得到和实际浏览器完全一样的DOM文档,会报很多的错误;其二就是HtmlUnit的选择器实在是十分难用。

HtmlUnit对JavaScript的支持是其最大的亮点,也是其最需要完善的地方。总的来说HtmlUnit是一款很棒的java工程,值得我们花一些时间来学习和尝试,给我们的武器库增加一件武器,也许什么时候你就会用到它。

本示例程序只是为学习和交流,不能用于商业目的,下载的数据所有权归属原单位。

5.原文地址:

www.42du.cn

© 著作权归作者所有

共有 人打赏支持
毛三胖
粉丝 0
博文 17
码字总数 17913
作品 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
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
模拟浏览器的神器 - HtmlUnit

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

杨尚川
2014/04/04
0
6

没有更多内容

加载失败,请刷新页面

加载更多

nacos之springboot

本地操作系统:ubuntu18,我使用docker的方式启动nacos服务 docker image方式启动nacos 在docker hub上可以搜到nacos-server List-1.1 拉去最新的版本 mjduan@mjduan-ubuntu:/opt/software$ ...

克虏伯
40分钟前
3
0
指针数组和数组指针的区别

这两个名字不同当然所代表的意思也就不同。我刚开始看到这就吓到了,主要是中文太博大精深了,整这样的简称太专业了,把人都绕晕了。从英文解释或中文全称看就比较容易理解。 指针数组:arr...

天王盖地虎626
今天
3
0
Qt那些事0.0.18

今天要记一下Qt中的Resource。自我感觉理解的不错,但是还会难免有谬误,在日后有可能会更新,也有可能不会。 小声的念叨一句,女人心,海底针。 今天就直接跳过了关于QML在qrc文件中的介绍,...

Ev4n
今天
2
0
深入解析js的作用域、预解析机制

虽然,ES6在我们工作中应用得越来越广泛,但是还是很多项目保留着ES5的写法,所以,今天,带着大家重新巩固下ES5下的作用域及预解析机制。 概念: 作用域:域,指的是一个空间、范围、区域,...

前端攻城老湿
今天
2
0
Spring Cloud Feign - 声明式 REST Client

1、Feign是什么 声明式REST client,来自NetFlix。 允许你编写无实现代码调用REST services 替换RestTemplate(甚至更简单) Spring Cloud 为使用Feign提供了包装器 2、怎样使用Feign 对比:...

Benz001
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部