使用 HttpClient 和 HtmlParser 实现简易爬虫
简介:?这篇文章介绍了 HtmlParser 开源包和 HttpClient 开源包的使用,在此基础上实现了一个简易的网络爬虫 (Crawler),来说明如何使用 HtmlParser 根据需要处理 Internet 上的网页,以及如何使用 HttpClient 来简化 Get 和 Post 请求操作,构建强大的网络应用程序。
使用 HttpClient 和 HtmlParser 实现简易爬虫
这篇文章介绍了 HtmlParser 开源包和 HttpClient 开源包的使用,在此基础上实现了一个简易的网络爬虫 (Crawler),来说明如何使用 HtmlParser 根据需要处理 Internet 上的网页,以及如何使用 HttpClient 来简化 Get 和 Post 请求操作,构建强大的网络应用程序。
HttpClient 与 HtmlParser 简介
本小结简单的介绍一下 HttpClinet 和 HtmlParser 两个开源的项目,以及他们的网站和提供下载的地址。
HttpClient 简介
HTTP 协议是现在的因特网最重要的协议之一。除了 WEB 浏览器之外, WEB 服务,基于网络的应用程序以及日益增长的网络计算不断扩展着 HTTP 协议的角色,使得越来越多的应用程序需要 HTTP 协议的支持。虽然 JAVA 类库 .net 包提供了基本功能,来使用 HTTP 协议访问网络资源,但是其灵活性和功能远不能满足很多应用程序的需要。而 Jakarta Commons HttpClient 组件寻求提供更为灵活,更加高效的 HTTP 协议支持,简化基于 HTTP 协议的应用程序的创建。 HttpClient 提供了很多的特性,支持最新的 HTTP 标准,可以访问这里了解更多关于 HttpClinet 的详细信息。目前有很多的开源项目都用到了 HttpClient 提供的 HTTP功能,登陆网址可以查看这些项目。本文中使用 HttpClinet 提供的类库来访问和下载 Internet上面的网页,在后续部分会详细介绍到其提供的两种请求网络资源的方法: Get 请求和 Post 请求。Apatche 提供免费的 HTTPClien t源码和 JAR 包下载,可以登陆这里?下载最新的HttpClient 组件。笔者使用的是 HttpClient3.1。
HtmlParser 简介
当今的 Internet 上面有数亿记的网页,越来越多应用程序将这些网页作为分析和处理的数据对象。这些网页多为半结构化的文本,有着大量的标签和嵌套的结构。当我们自己开发一些处理网页的应用程序时,会想到要开发一个单独的网页解析器,这一部分的工作必定需要付出相当的精力和时间。事实上,做为 JAVA 应用程序开发者, HtmlParser 为其提供了强大而灵活易用的开源类库,大大节省了写一个网页解析器的开销。 HtmlParser 是?http://sourceforge.net?上活跃的一个开源项目,它提供了线性和嵌套两种方式来解析网页,主要用于 html 网页的转换(Transformation) 以及网页内容的抽取 (Extraction)。HtmlParser 有如下一些易于使用的特性:过滤器 (Filters),访问者模式 (Visitors),处理自定义标签以及易于使用的 JavaBeans。正如 HtmlParser 首页所说:它是一个快速,健壮以及严格测试过的组件;以它设计的简洁,程序运行的速度以及处理 Internet 上真实网页的能力吸引着越来越多的开发者。 本文中就是利用HtmlParser 里提取网页里的链接,实现简易爬虫里的关键部分。HtmlParser 最新的版本是HtmlParser1.6,可以登陆这里下载其源码、 API 参考文档以及 JAR 包。
回页首
开发环境的搭建
笔者所使用的开发环境是 Eclipse Europa,此开发工具可以在?www.eclipse.org?免费的下载;JDK是1.6,你也可以在www.java.sun.com?站点下载,并且在操作系统中配置好环境变量。在 Eclipse 中创建一个 JAVA 工程,在工程的 Build Path 中导入下载的Commons-httpClient3.1.Jar,htmllexer.jar 以及 htmlparser.jar 文件。
图 1. 开发环境搭建
?
回页首
HttpClient 基本类库使用
HttpClinet 提供了几个类来支持 HTTP 访问。下面我们通过一些示例代码来熟悉和说明这些类的功能和使用。 HttpClient 提供的 HTTP 的访问主要是通过 GetMethod 类和 PostMethod 类来实现的,他们分别对应了 HTTP Get 请求与 Http Post 请求。
GetMethod
使用 GetMethod 来访问一个 URL 对应的网页,需要如下一些步骤。
清单 1 的代码展示了这些步骤,其中的注释对代码进行了较详细的说明。
清单 1.
这里值得注意的几个地方是:
- 设置连接超时和请求超时,这两个超时的意义不同,需要分别设置。
- 响应状态码的处理。
- 返回的结果可以为字节数组,也可以为 InputStream,而后者在网页内容数据量较大的时候推荐使用。
在处理返回结果的时候可以根据自己的需要,进行相应的处理。如笔者是需要保存网页
到本地,因此就可以写一个 saveToLocaleFile(byte[] data, String filePath) 的方法,将字节数组保存成本地文件。后续的简易爬虫部分会有相应的介绍。
PostMethod
PostMethod 方法与 GetMethod 方法的使用步骤大体相同。但是由于 PostMethod 使用的是HTTP 的 Post 请求,因而请求参数的设置与 GetMethod 有所不同。在 GetMethod 中,请求的参数直接写在 URL 里,一般以这样形式出现:http://hostname:port//file?name1=value1&name2=value …。请求参数是 name,value 对。比如我想得到百度搜索“Thinking In Java”的结果网页,就可以使 GetMethod 的构造方法中的 url 为:http://www.baidu.com/s?wd=Thinking+In+Java 。而 PostMethod 则可以模拟网页里表单提交的过程,通过设置表单里 post 请求参数的值,来动态的获得返回的网页结果。清单 2 中的代码展示了如何创建一个 Post 对象,并设置相应的请求参数。
清单2回页首HtmlParser 基本类库使用
HtmlParser 提供了强大的类库来处理 Internet 上的网页,可以实现对网页特定内容的提取和修改。下面通过几个例子来介绍 HtmlParser 的一些使用。这些例子其中的代码,有部分用在了后面介绍的简易爬虫中。以下所有的代码和方法都在在类 HtmlParser.Test.java 里,这是笔者编写的一个用来测试 HtmlParser 用法的类。
网页是一个半结构化的嵌套文本文件,有类似 XML 文件的树形嵌套结构。使用HtmlParser 可以让我们轻易的迭代遍历网页的所有节点。清单 3 展示了如何来实现这个功能。
清单 3
如果你想要网页中去掉所有的标签后剩下的文本,那就是用 StringBean 吧。以下简单的代码可以帮你解决这样的问题:
清单5
StringBean sb = new StringBean();
sb.setLinks(false);//设置结果中去点链接
sb.setURL(url);//设置你所需要滤掉网页标签的页面 url
System.out.println(sb.getStrings());//打印结果
HtmlParser 提供了强大的类库来处理网页,由于本文旨在简单的介绍,因此只是将与笔者后续爬虫部分有关的关键类库进行了示例说明。感兴趣的读者可以专门来研究一下 HtmlParser 更为强大的类库。
回页首
简易爬虫的实现
HttpClient 提供了便利的 HTTP 协议访问,使得我们可以很容易的得到某个网页的源码并保存在本地;HtmlParser 提供了如此简便灵巧的类库,可以从网页中便捷的提取出指向其他网页的超链接。笔者结合这两个开源包,构建了一个简易的网络爬虫。
爬虫 (Crawler) 原理
学过数据结构的读者都知道有向图这种数据结构。如下图所示,如果将网页看成是图中的某一个节点,而将网页中指向其他网页的链接看成是这个节点指向其他节点的边,那么我们很容易将整个 Internet 上的网页建模成一个有向图。理论上,通过遍历算法遍历该图,可以访问到Internet 上的几乎所有的网页。最简单的遍历就是宽度优先以及深度优先。以下笔者实现的简易爬虫就是使用了宽度优先的爬行策略。
图 2. 网页关系的建模图
?
简易爬虫实现流程
在看简易爬虫的实现代码之前,先介绍一下简易爬虫爬取网页的流程。
图 3. 爬虫流程图
?
各个类的源码以及说明
对应上面的流程图,简易爬虫由下面几个类组成,各个类职责如下:
Crawler.java:爬虫的主方法入口所在的类,实现爬取的主要流程。
LinkDb.java:用来保存已经访问的 url 和待爬取的 url 的类,提供url出对入队操作。
Queue.java: 实现了一个简单的队列,在 LinkDb.java 中使用了此类。
FileDownloader.java:用来下载 url 所指向的网页。
HtmlParserTool.java: 用来抽取出网页中的链接。
LinkFilter.java:一个接口,实现其 accept() 方法用来对抽取的链接进行过滤。
下面是各个类的源码,代码中的注释有比较详细的说明。
清单6 Crawler.java
http://www.twt.edu.cn 开头的链接public boolean accept(String url) {if(url.startsWith("http://www.twt.edu.cn"))return true;elsereturn false;}});for(String link : links)System.out.println(link);}}清单11 LinkFilter.javapackage com.ie;public interface LinkFilter {public boolean accept(String url);}
这些代码中关键的部分都在 HttpClient 和 HtmlParser 介绍中说明过了,其他部分也比较容易,请感兴趣的读者自行理解。
总结
这篇文章主要是介绍与展示了如何使用开源的 HttpClinet 包和 HtmlParser 包,以及结合这两者来给出了一个简易网络爬虫程序的实现,当然这个爬虫与实际真正的爬虫还是有所差距。由于更多的目的是关注这两个开源包的运用,加上本文篇幅有限,因此,没有对这两个开源包做非常详尽的介绍。希望这篇文章能够引导读者对 HttpClient 包和 HtmlParser 产生兴趣,从而利用他们构建强大的 JAVA 网络应用程序。
文章出处:https://www.ibm.com/developerworks/cn/opensource/os-cn-crawler/
?