1. 什么是HtmlUnit?
HtmlUnit是一个无界面浏览器Java程序。它为HTML文档建模,提供了调用页面、填写表单、单击链接等操作的API。就跟你在浏览器里做的操作一样。HtmlUnit不错的JavaScript支持(不断改进),甚至可以使用相当复杂的Ajax库,根据配置的不同模拟Chrome、Firefox或Internet Explorer等浏览器。HtmlUnit通常用于测试或从web站点检索信息。
2. 它可以干啥?
它可以读取页面所有元素
eg:现在有一个需求是客户给了一个.chm说明文档,文件中记录了表和字段的关系和注释,现在需要将注释添加到数据库中,首先可以通过工具将chm文件转换成html文件,然后我们就可以通过爬取html文件实现这个功能;
它可以模拟用户进行点击,这个功能就可以实现登录,跳转页面等等;
eg:现在有一个需求是客户那边有一个系统里边包含了很多数据,但是因为安全性问题我们的系统不能够直连它的数据库,所以现在需要实时的展示客户那边系统的数据,需要怎么做呢?可以通过爬虫做一个 “适配器”,它的大致原理是 当用户点击我们的系统点击查看 “人员信息” 时,我们的系统通过爬虫实时获取客户系统页面上的数据,在返回给我们的系统进行展示。
3. 大体流程
需求:现在想通过Java程序实现爬取新浪新闻的一些内容
创建新浪网站实例
通过表达式获取你想获取的标签元素
4. 项目代码
pom文件
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.23</version>
</dependency>
public class XinLangNews {
public static void main(String args[]) throws Exception {
WebClient webClient = new WebClient(BrowserVersion.CHROME);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
webClient.getOptions().setActiveXNative(false);
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
webClient.waitForBackgroundJavaScript(30000);
HtmlPage page = webClient.getPage("https://news.sina.com.cn/");
List<HtmlSpan> byXPath = (List<HtmlSpan>) page.getByXPath("//*[@id=\"blk_cNav2_01\"]/div/a/span");
byXPath.forEach((x) -> {
System.out.println(x.getTextContent());
注意:运行的时候控制台可能很多报错,不要慌,这些错是html页面上js报的错
说明:下面这三步很重要,它可以读取到js和ajax动态加载的内容
webClient.getOptions().setJavaScriptEnabled(true);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
webClient.waitForBackgroundJavaScript(30000);
5. 奇淫技巧
在用HtmlUnit写一个爬虫项目的时候,创建WebClient客户端基本都是固定格式,最麻烦的还是获取dom元素,这里我讲介绍一种非常方便的获取dom元素的方法;这里我通过上面的新浪新闻网站进行介绍;
首先打开chrome,然后进入到https://news.sina.com.cn/,按F12打开开发者模式,找到你想要获取到的页面元素,此时在chrome的Elements模块中选择需要获取的元素点击“右键”,选择Copy-->Copy XPath,此时就获取到了该元素在整个页面的xpath路径,图中 “滚动” 的xpath路径为 //[@id="blk_cNav2_01"]/div/a[1]/span,由于我想获取所有span(也就是 滚动,排行,政务等等),所以可以将上面复制过来的xpath路径改写为//[@id="blk_cNav2_01"]/div/a/span,把a[1]改成a即可,此时大功告成。你们可以通过这个方法快速准确的定位到元素
6. 未完待续
比如Jsoup,WebClient和HttpClient都可以实现页面爬虫效果,但是他们有什么区别呢?这篇文章将在下期揭晓;
本文使用 mdnice 排版