欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

htmlunit带来的大坑 插入数据Mysql 导致CPU消耗爆棚100%

程序员文章站 2022-05-05 14:48:54
...

最近公司工作中接到商品部的需求,进行爬取网站中的所有商品信息进行入库,配合公司市场部商品部进行做市场战略分析,故而使用springboot + htmlunit 进行爬取数据信息,将其入库MySQL进行数据导出,结果因为htmlunit的一个小小配置导致了CPU的消耗高额爆出,同时还导致了GC的一系列的内存溢出等等,坑坏了我一个下午的时间,而且插入数据库的速度超级的慢(数据量才1W+,入库已做批量插入),现在记录下来  希望能帮到大家。

1.什么是htmlunit 

     htmlunit 是一款开源的java 页面分析工具,读取页面后,可以有效的使用htmlunit分析页面上的内容。项目可以模拟浏览器运行,被誉为java浏览器的开源实现。是一个没有界面的浏览器,运行速度迅速。是junit的扩展之一;采用的是Rhinojs引擎。模拟js运行,非常适用于小型爬虫项目,可以有效的分析出 dom的标签,并且有效的运行页面上的js以便得到一些需要执行JS才能得到的值。

2.配置实例(把它抽成工具类,可以直接拿来用)

public class WebClientUtil {

    /**
     * 处理异步加载  爬取内容
     * @author *******
     * @date 2019/2/19 9:37No such property: code for class: Script1
     * @return com.gargoylesoftware.htmlunit.html.HtmlPage
     */
    public static HtmlPage htmlunitCrawler(String url) throws Exception{

        //构造一个webClient 模拟Chrome 浏览器
        WebClient webClient = new WebClient(BrowserVersion.CHROME);
        //屏蔽日志信息
        java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
        //支持JavaScript
        webClient.getOptions().setJavaScriptEnabled(false);
        webClient.getOptions().setCssEnabled(false);
        webClient.getOptions().setActiveXNative(false);
        webClient.getOptions().setCssEnabled(false);
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
        webClient.getOptions().setTimeout(5000);
        HtmlPage rootPage = webClient.getPage(url);
        //设置一个运行JavaScript的时间
        webClient.waitForBackgroundJavaScript(5000);
        return rootPage;
    }

}

 如果不加webClient.getOptions().setThrowExceptionOnScriptError(false);这一句或者将webClient.getOptions().setThrowExceptionOnScriptError(true);都将会导致以上的问题,分享出来,希望可以帮到大家。

如果我们必须使用webClient.getOptions().setThrowExceptionOnScriptError(true);那么我们必须添加

  1. webClient.getCurrentWindow().getJobManager().removeAllJobs();

  2. webClient.close();

  3. System.gc();

  4. 如图

    finally {
                    try {
                        htmlunitCrawler().getCurrentWindow().getJobManager().removeAllJobs();
                        htmlunitCrawler().close();
                        System.gc();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

     

相关标签: htmlunit