【Jsoup】配合 htmlunit 爬取异步加载的网页

来源:互联网 发布:python 创建临时文件 编辑:程序博客网 时间:2024/05/29 17:09

不知道大家在使用 jsoup 的过程中有没有遇到爬取内容时,发现有的网页里面的内容时通过 JavaScript 异步加载的数据,导致我们的爬虫空手而归(只抓到一个网页的外框)。

首先再遇到这个问题的时候想到的解决方案有两种:

  1. 使用类似 Python 中延迟加载的方式使等待网页异步加载完成后爬取异步加载完成的网页
  2. 使用某种特殊的方法使爬取出来的网页外框模拟执行里面的 JavaScript 代码,最终到达获取完整的网页

在搜索引擎的帮助之下,确定了使用方案2 来解决该问题,方案1 没有搜索到较好的第三方库,有在 java 中使用方案1来解决这个问题的朋友希望可以与在下探讨一番,不胜感激。

案例很简单,抓一个今日头条的首页内容。大家可以去看一下今日头条的首页,里面的内容时异步加载的。
https://www.toutiao.com/

加入 jsoup 和 htmlunit 的依赖

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

首先我们单独使用 jsoup 来解析今日头条的首页

String url = "https://www.toutiao.com/";Connection connect = Jsoup.connect(url);Document document = connect.get();System.out.println(document);

↑ 这里我们只能获取到网页的框架内容,获取不到首页上面的新闻内容

下面,我们使用 htmlunit 来试试

//构造一个webClient 模拟Chrome 浏览器WebClient webClient = new WebClient(BrowserVersion.CHROME);//屏蔽日志信息LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log",        "org.apache.commons.logging.impl.NoOpLog");java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);//支持JavaScriptwebClient.getOptions().setJavaScriptEnabled(true);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);String html = rootPage.asXml();Document document = Jsoup.parse(html);

这样我们就可以得到一个包含运行 JavaScript 之后的完整源网页了