常用的Java网络爬虫库
Java 开发语言是业界使用最广泛的开发语言之一,在互联网从业者中具有广泛的使用者,Java 网络爬虫可以帮助 Java 开发人员以快速、简单但广泛的方式为各种目的抓取数据。平常我们在讨论网络爬虫的时候,很多人都会想到使用 Python 语言,因为与 Python 相关的网络爬虫资料很多,框架也有不少,上手会方便不少。但实际上,Java 网络爬虫家族里面也有很多优秀的开源框架或者开源库供大家使用。下图是国外某个网站在某年度筛选出来的最受欢迎的 50 个网络爬虫开源框架或者开源库,从这个排名中我们可以看出 Java 网络爬虫的应用也是很广泛的。
接下来给大家介绍几个常用的Java开源网络爬虫库:
1.Heritrix
Heritrix 是一个完全由 Java 开发的、开源网络爬虫工具,用户可以使用它从网络上面抓取想要的资源。它的主要组件包括 Web Administrative Console、Crawl Order、Crawl Controller、Frontier、Scope、ToeThreads 和 Processor 等。在国内,Heritrix 也有着十分广泛的使用者,很多开发人员和研究人员都在使用 Heritrix 来采集数据,为进一步的数据分析和数据挖掘工作做准备。Heritrix 的最出色之处在于开发者可以在现有框架的基础上面对各个组件进行扩展,实现自己需要的抓取逻辑。其整体结构如下图所示:
一个完整的网页采集任务是从 CrawlOrder 开始的。用户可以通过多种不同方法创建 一个网页采集任务,例如复制已经存在的任务、手动创建新的任务等,其中最方便的方法 是利用默认的配置文件 order.xml 来创建一个任务。这个文件中记录了抓取任务的所有属 性,每次配置一个新的任务都会产生一个新的 order.xml 文件,Heritrix 中的 CrawlOrder 组件就是用来存储 order.xml 文件中的内容。
Heritrix 采用了良好的模块化设计,这些模块由一个采集控制器类(CrawlerController)来协调调度,CrawlerController 在架构中处于核心地位,其主要工作结构如下图所示:
接下来,给大家稍微介绍一下上图中提到的各个工作组件。
CrawlController 在执行抓取任务的过程中,作为一个主线程在工作,CrawlController 决定着如何开始抓取工作,并决定着何时开始、何时结束数据采集工作。
Frontier 组件的任务是为线程提供链接,它借助一些算法来判断采集到的 URI 是否会 被处理,同时它也负责记录日志和报告爬虫的运行状态。
Frontier 组件中有一个属性叫做 scope,它决定了当前抓取范围的组件。通过配置抓取范围,可以决定爬虫是在一个域名下抓取还是在多个域名下抓取。
Heritrix 支持多线程运行,因此 Heritrix 内部维护了标准线程池 ToePool, 这个线程池用于管理爬虫中的所有线程,每一个线程在处于运行状态时只处理一个 URL。 采用多线程的技术可以提高爬虫采集网页的效率,以便更快速有效地抓取网页内容。负责处理的线程叫做 ToeThread,ToeThread 从 Frontier 中请求待处理的 URL 后,发送给处理器进行处理。
在 Heritrix 中,处理器被分组为处理器链。每个处理器链都会对 URL 进行一些处理。当一个处理器处理完一个 URL 后,ToeThread 会将 URL 发送给下一个处理器,直到 URL 被所有处理器处理完毕。处理器可以选择告诉 URL 跳转到某个特定的链。此外,如果处理器出现致命错误,处理将跳至后处理链。处理器链的工作流程如下图所示:
下面对各个处理链进行一下简单介绍:
(1)Pre-fetch processing chain(预处理链)
预处理链负责检查 URL 是否符合抓取规则,是否在抓取范围内。在预处理链中,包含两个主要的处理器,Preselector 和 PreconditionEnforcer。
PreSelector 用来检查 URL 是否符合采集任务的需要,以便判断是 否要继续处理该 URL,它可以将一部分不满足需求的 URL 过滤掉。这里主要是 通过正则表达式匹配 URL,如果一个 URL 满足正则表达式,这个 URL 会进入 下一步的处理;否则就抛弃这个 URL。
PreconditionEnforcer 的作用是确保抓取一个 URL 的所有先 决条件都已经满足,例如验证 DNS 是否成功解析、robots 信息是否已经获取等。
(2)Fetch processing chain(抓取处理链)
抓取处理链中的处理器中的处理器主要负责从服务器获取数据,Heritrix 支持的 每个网络协议都有一个与之对应的处理器,例如 HTTP 协议对应的是 FetchHTTP 处理器。
(3)Extractor processing chain(提取器处理链)
在提取器处理链中,URL 所引用的文档内容处于可用的状态,多个处理器将依次尝试从中获取新链接。与抓取处理链一样,每个网络协议都有一个与之对应的提取处理器,例如:ExtractorHTTP、ExtractorFTP 等。
(4)Write/index processing chain (存档处理链)
该链负责将数据写入归档文件。Heritrix 自带的 ARCWriterProcessor 可将数据写入 ARC 格式。还可以编写新的处理器来支持其他格式,甚至创建索引。
(5)Post-processing chain(后处理链)
URL 应始终通过该处理链,即使在该链中较早的处理器已决定不抓取该 URL。后处理链必须包含以下处理器:
- CrawlStateUpdater: 用于更新每一台可能在采集过程中受到爬虫影响的主机的信 息,这里的信息包括 robots 信息和 IP 地址。
- LinksScoper:主要用于验证链接的范围。验证从网页中抽取出来的 URL 是否在 规定的范围内,并过滤掉不在该范围内的 URL。
- FrontierScheduler: 将提取到的链接放入到 Frontier 中,以便后续调度抓取。
优缺点
优点:开发者可以方便地在现有框架基础上进行扩展
缺点:单实例的爬虫,无法在分布式环境下进行工作;应对反爬虫的机制比较薄弱
实战篇:
安装及配置
下载地址: https://github.com/internetarchive/heritrix3
我这里使用的版本是 3.4.0,安装方法简单,只要参考官方文档就可以了。
启动及运行
启动的时候,我们可以选择通过命令行启动:
$HERITRIX_HOME/bin/heritrix -a admin:123456
也可以选择将工程源代码导入到 IDE 后,在 IDE 中启动。无论选择哪种启动方式,都需要注意添加参数-a 来设置用户名和密码。
engine listening at port 8443
operator login set per command-line
NOTE: We recommend a longer, stronger password, especially if your web interface will be internet-accessible.
Heritrix version: 3.4.0-20220727
运行之后看到上面的日志信息就代表启动成功了。
在浏览器中访问: https://localhost:8443 ,可以进入到管理界面。
注意:一定要是 https 链接才可以,因为 Heritrix 在启动 web 容器的时候只支持了 https 协议,而没有支持 http 协议,因为本地没有设置证书,所以会出现安全警告,忽略继续访问就可以的。
抓取任务创建与配置
启动成功以后,我们就可以创建和配置抓取任务了。
在创建任务的过程中,最重要的就是通过 configuration 选项配置抓取任务。通过一个名为 crawler-beans.cxml 的配置文件控制整个抓取过程。crawler-beans.cxml 采用 Spring 来管理,里面的配置都是 spring bean。下面对 crawler-beans.cxml 文件中涉及到的 spring bean 进行简单介绍。
bean id | class | 作用 |
---|---|---|
simpleOverrides和longerOverrides | org.springframework.beans.factory.config.PropertyOverrideConfigurer | 属性资源配置器覆盖应用程序上下文定义中的 bean 属性值。它将属性文件中的值推送到 bean 定义中。 |
metadata | org.archive.modules.CrawlMetadata | 该bean的主要作用是记录抓取job的基本属性,名称、抓取地址和robots协议规则的遵循。 |
seeds | org.archive.modules.seeds.TextSeedModule | 该bean的主要作用是设置种子地址的读取位置 |
acceptSurts | org.archive.modules.deciderules.surt.SurtPrefixedDecideRule | surtprefixeddeciderule是Heritrix3中的一个决策规则(DecideRule),它的作用是允许或禁止基于URL前缀的抓取。 |
scope | org.archive.modules.deciderules.DecideRuleSequence | Deciderulesequence的作用是定义和控制抓取流程中的决策规则序列。 |
candidateScoper | org.archive.crawler.prefetch.CandidateScoper | Candidatescoper会根据一系列的规则或算法,对网页进行判断和打分。例如,它可以根据网页的URL结构、网页内容的关键词匹配、链接的可用性等因素,来评估网页的重要性和质量。根据这些评估标准,Candidatescoper会给每个网页打上一个分数,分数高的网页将被优先保留。 |
preparer | org.archive.crawler.prefetch.FrontierPreparer | FrontierPreparer主要作用是设置URL的抓取深度,队列,成本控制等。 |
candidateProcessors | org.archive.modules.CandidateChain | 主要作用是管理待爬取的URL,CandidateChain引用了candidateScoper来决定相关的URL是否会保留并生成CrawlURI,同时还引用了prepare bean来控制抓取的深度并进行成本控制等。 |
preselector | org.archive.crawler.prefetch.Preselector | 预先选择器,这里会过滤掉一部分URL.如blockByRegex为拒绝正则,allowByRegex为允许正则 |
preconditions | org.archive.crawler.prefetch.PreconditionEnforcer | 先决条件设置,如设置IP有效期,爬虫协议文件robots.txt有效期 |
fetchDns | org.archive.modules.fetcher.FetchDNS | FetchDNS主要用于处理域名解析功能 |
extractorHttp | org.archive.modules.extractor.ExtractorHTTP | URL提取器 |
extractorRobotsTxt | org.archive.modules.extractor.ExtractorRobotsTxt | 查看Robots协议 |
ExtractorSitemap | org.archive.modules.extractor.ExtractorSitemap | extractorsitemap是heritrix中的一个用来处理网站地图(sitemap)的抽取器。 |
ExtractorHTML | org.archive.modules.extractor.ExtractorHTML | HTML内容提取器 |
配置好各个选项之后,我们就可以开始真正执行抓取任务了。因为篇幅的关系这里就不展开描述了,感兴趣的读者可以自行实践。
2.Norconex Web Crawler
官方地址: https://opensource.norconex.com/crawlers/web/
Norconex 也是一款非常优秀的开源爬虫工具,与之相关的中文资料比较少。但是,如果你正在寻找一个开源的企业级爬虫工具,那你一定不能错过它。作者认为 Norconex Web Crawler 有两个功能最值得关注:
- 支持多种类型的 HTML 文档下载器。当我们要采集网页中的特定信息时,我们首先要能够下载网页的内容,Norconex 提供了 GenericHttpFetcher 来满足大部分场景下的需求,但是在某些情况下,可能需要更专业的方式来获取网络资源。例如:通过 Javascript 异步加载的网页内容,则通过 WebDriverHttpFetcher 来获取网页内容更加合理。当然,你也可以开发自定义的 HTML 文档下载器。
- 提供了 HTTP 请求头和 HTTP 响应头监听器和修改器。Norconex 基于 BrowserMobProxy 实现了 HTTP 请求头和 HTTP 响应头监听器和修改器(HttpSniffer)。HttpSniffer 使得对 HttpFetcher 请求和响应内容的监控更加方便,也可以使 HTTP 的请求更加规范化,而且可以多一种方式获取到 web 服务响应的内容。
接下来,我们重点介绍一下 BrowserMobProxy(简称 BMP),它是一款由 Java 编写开源的网络访问代理工具,在后面我们自己编写的 Java 网络爬虫中也会用到该工具。通过 BMP,我们可以修改、设置和捕获到网络的请求和响应,BMP 甚至可以将网络请求的所有细节记录到 HAR 文件中。Har 是一种用于导出 HTTP 跟踪信息的开放格式,称为 HTTP 存档 (HAR)。数据存储格式为 JSON 文档。具体信息可以参见( RFC 4627 )。BMP 有两种工作模式,嵌入式模式和独立启动模式。嵌入式模式是通过 Java 代码调用使用。嵌入式模式是利用 Java 代码来启动代理,并通过 Java 代码来捕获修改请求信息和响应信息。另一种是独立启动模式,可以通过命令行来启动,通过 RestAPI 来进行操作。
3. Crawler4j
Crawler4j是用Java编写的开源项目,它支持多线程方式采集网站信息,并利用正则表达式限制采集对象。Crawler4j具有完整的爬虫功能框架,小巧灵活并可以独立运行。因此,易于集成到项目中,或者将第三方业务逻辑嵌入工作流中自定义爬行。其主要工作流程如下所示:
Crawler4j最主要的缺点是不支持动态网页的抓取,但是我们可以基于Crawler4j进行二次开发对WebCrawlerFactory进行扩展使其支持动态网页内容的抓取。
总结
本章中,我们介绍了几个目前仍然比较活跃的爬虫开源框架,Heritrix,Norconex和Crawler4j。在后面的章节里面,我们会参考这些开源的框架和软件,开发一套属于我们自己的Java爬虫软件。