package org.spider.htmlunit;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.util.Cookie;
import org.jsoup.helper.StringUtil;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 * @description:
 * @author: long.li
 * @date: 2019/2/20 14:40
public class HtmlUnitUtils {
    public static void main(String[] args) throws Exception {
        HtmlUnitBuilder builder = HtmlUnitBuilder.config()
                .url("www.baidu.com")
                .enableJS(true)
                .enableCookie(true);
        getPage(builder).asText();
    public static HtmlPage getPage(HtmlUnitBuilder builder)throws Exception{
        WebClient webClient = getWebClient(builder);
        int count = -1;
        while(true){
            try {
                count++;
                return webClient.getPage(builder.url());
            catch (Exception e){
                if(e instanceof IOException && count < builder.retry()){
                    //日志打印:e,重试次数:i,再次执行
                }else {//如果url错误等情况
                    //执行失败,抛出异常
                    throw e;
    public static WebClient getWebClient(HtmlUnitBuilder builder){
        WebClient webClient = null;
        if(isBlank(builder.proxyHost())){
            webClient = new WebClient(BrowserVersion.CHROME);
        }else{
            webClient = new WebClient(BrowserVersion.CHROME,builder.proxyHost(),builder.proxyPort());
            if(!isBlank(builder.username())){ //需要验证的代理服务器
                ((DefaultCredentialsProvider) webClient.getCredentialsProvider()).
                        addCredentials(builder.username(),builder.password());
        //浏览器基本设置
        webClient.getOptions().setThrowExceptionOnScriptError(false);//当JS执行出错的时候是否抛出异常
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//当HTTP的状态非200时是否抛出异常
        webClient.getOptions().setCssEnabled(builder.enableCSS());//是否启用CSS
        webClient.getOptions().setJavaScriptEnabled(builder.enableJS()); //默认设置为禁用
        if(builder.enableAjax()) {
            webClient.setAjaxController(new NicelyResynchronizingAjaxController());//设置支持AJAX
        if(builder.enableCookie()){
            webClient.getCookieManager().setCookiesEnabled(true);
            for(Map.Entry<String,String> pair:builder.cookies().entrySet()){
                webClient.getCookieManager().addCookie(new Cookie("/",pair.getKey(),pair.getKey()));
        webClient.waitForBackgroundJavaScript(builder.waitForBackgroundJavaScript());
        Map<String,String> headers = builder.headers();
        if(headers!=null&&headers.size()>0){
            for(Map.Entry<String,String> header:headers.entrySet()){
                webClient.addRequestHeader(header.getKey(),header.getValue());
        return webClient;
     * org.jsoup.helper.StringUtil
     * @param string
     * @return
    private static boolean isBlank(String string) {
        if (string == null || string.length() == 0)
            return true;
        int l = string.length();
        for (int i = 0; i < l; i++) {
            if (!StringUtil.isWhitespace(string.codePointAt(i)))
                return false;
        return true;
    private static boolean isWhitespace(int c){
        return c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r';

二. HtmlUnitBuilder

package org.spider.htmlunit;
import java.util.HashMap;
import java.util.Map;
 * @description:
 * @author: long.li
 * @date: 2019/2/20 14:40
public class HtmlUnitBuilder {
    private String url; //请求URL
    private String proxyHost; //代理服务器地址
    private int proxyPort; //代理服务器端口
    private String username; //代理服务器账户
    private String password; //代理服务器密码
    private boolean enableCSS = false; //CSS支持
    private boolean enableJS = false; //JavaScript支持
    private boolean enableAjax = false; //Ajax支持
    private boolean enableCookie = false;//cookie支持
    private int waitForBackgroundJavaScript = 0; //等待JS加载时间
    private int retry = 0; //请求异常重试次数
    private Map<String, String> headers = new HashMap<>(); //请求头参数
    private Map<String, String> cookies = new HashMap<>(); //cookie
    public static HtmlUnitBuilder config() {
        return new HtmlUnitBuilder();
    public HtmlUnitBuilder url(String url) {
        this.url = url;
        return this;
    public HtmlUnitBuilder retry(int retry) {
        this.retry = retry;
        return this;
     * 不需要验证的代理服务器
     * @param proxyHost
     * @param proxyPort
     * @return
    public HtmlUnitBuilder proxy(String proxyHost, int proxyPort) {
        this.proxyHost = proxyHost;
        this.proxyPort = proxyPort;
        return this;
     * 需要验证的代理服务器
     * @param proxyHost
     * @param proxyPort
     * @param username
     * @param password
     * @return
    public HtmlUnitBuilder proxy(String proxyHost, int proxyPort,
                                 String username, String password) {
        this.proxyHost = proxyHost;
        this.proxyPort = proxyPort;
        this.username = username;
        this.password = password;
        return this;
    public HtmlUnitBuilder enableCSS(boolean enableCSS) {
        this.enableCSS = enableCSS;
        return this;
    public HtmlUnitBuilder enableJS(boolean enableJS) {
        this.enableJS = enableJS;
        return this;
    public HtmlUnitBuilder enableAjax(boolean enableAjax) {
        this.enableAjax = enableAjax;
        return this;
    public HtmlUnitBuilder enableCookie(boolean enableCookie) {
        this.enableCookie = enableCookie;
        return this;
    public HtmlUnitBuilder cookies(Map<String, String> cookies){
        this.cookies = cookies;
        return this;
     * 设置新的请求头集合
     * @param headers
     * @return
    public HtmlUnitBuilder headers(Map<String, String> headers) {
        this.headers = headers;
        return this;
     * 添加请求头参数
     * @param key   键
     * @param value 值
     * @return
    public HtmlUnitBuilder addHeader(String key, String value) {
        headers.put(key, value);
        return this;
    public HtmlUnitBuilder waitForBackgroundJavaScript(int waitForBackgroundJavaScript) {
        this.waitForBackgroundJavaScript = waitForBackgroundJavaScript;
        return this;
    public String url() {
        return url;
    public int retry() {
        return retry;
    public String proxyHost() {
        return proxyHost;
    public int proxyPort() {
        return proxyPort;
    public String username() {
        return username;
    public String password() {
        return password;
    public boolean enableCSS() {
        return enableCSS;
    public boolean enableJS() {
        return enableJS;
    public boolean enableAjax() {
        return enableAjax;
    public boolean enableCookie() {
        return enableCookie;
    public int waitForBackgroundJavaScript() {
        return waitForBackgroundJavaScript;
    public Map<String, String> headers() {
        return headers;
    public Map<String,String> cookies(){
        return cookies;
HtmlUnit不错的JavaScript支持(不断改进),甚至可以使用相当复杂的AJAX库,根据配置的不同模拟Chrome、Firefox或Internet Explorer等浏览器。
HtmlUnit通...
                                    爬取页面效果图点击”百度一下”按钮前页面点击”百度一下”按钮后页面天涯社区登录页面登录进去之后个人主页具体的实现代码pom.xml文件<!-- https://mvnrepository.com/artifact/net.sourceforge.htmlunit/htmlunit -->
    <dependency>
        <groupId>net.sourceforge.htmlun
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。
HttpClient 相比传统 JDK 自带的 URLConnection,增加了易用性和灵活性,它不仅是客户端发送 
                                    原文地址:http://www.haohaoblog.com/?p=1327&utm_source=tuicool
做Java编程的人其实,很多不懂SEO,也不知道如何让百度收录等等,当然,对于爬虫,网页抓取,也不是所有编程的人有考虑到,但是专门做这个人,还是需要了解一下这里面的知识的,那下面就来介绍一下一些爬虫和网页采集相关的组件和插件吧~
大家在做爬虫、网页采集、通过网页自动...
import java.net.MalformedURLException;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
                                    我使用发送关键字作为参数的HTMLUnit发送POST请求。该URL的一个例子是:使用HTMLUnit发送带有多个关键字作为参数的POST请求website.com/foo/bar/api?keywords=word1,word2,word3&language=en问题是我的应用程序动态地选择这些字和词的量可以高达10或20个甚至更多。如何将一组字作为值添加到HTTP请求中。我的代码目前是...
                                    我正在尝试访问网站,但无法将收集到的“ Cookie”添加到传出的POST请求标头中。我已经能够验证它们是否存在于CookieManager中。HtmlUnit的任何替代方法也将不胜感激。public static void main( String[] args ){// Turn off logging to prevent polluting the output.Logger.getLog...
                                    我点击一个按钮后,有一个程序被编写来从网页上抓取源代码。我无法刮取正确的页面,因为我认为正在发送AJAX请求,并且我不等待此响应发生。我的代码是目前:在Htmlunit中处理AJAX请求public class Htmlunitscraper {private static String s = "http://cpdocket.cp.cuyahogacounty.us/SheriffSearch...
                                    最近写爬虫的时候,利用httpclient抓取一些网页出现一些问题,就是抓取回来的内容都含有大量的加密文本(通过javascript脚本),无法获得真实的内容(也就是用浏览器打开网页呈现的内容)。所以,一般需要配合js引擎来解决这个问题,搜索了下,发现htmlunit这个工具就可以帮忙。了解和使用过程中,发现这是一个非常牛逼的开源工具,虽然名气比httpclient小,但是实力绝对不容小觑。 闲话...
2.关于抓取js加载出来的内容抓取 (参考了该博客的流程,例如找到实际的请求url)
以一篇新闻资讯为例:http://news.cqcoal.com/blank/nc.jsp?mid=98212
1.使用F12,在network中的文件列...
                                    elements,console,source,network
elements分析网络结构,获取想要的数据
console打印一些网站的数据,做网站的时候有时候可能会在控制台上打印一些数据
source源文件,相等于一个文件夹,不仅包含网络的元素,还包含一些其他的内容,
如果是静态数据,在elements当中就可以查看到,如果是动态数据在elements之中无法查看
比如说我们在百度之中搜索美女,会出现各种美女图片,此时随着我们下拉的过程,滚动条会越变越小,然后我们搜索网页源代码之中的关键信息
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供...