WebCollector内核解析—如何设计一个爬虫

标签: webcollector 内核 解析 | 发表时间:2014-09-27 21:03 | 作者:AJAXHu
出处:http://blog.csdn.net

本文利用 WebCollector内核的解析,来描述如何设计一个网络爬虫。我们先来看看两个非常优秀爬虫的设计。

Nutch

Nutch由apache开源组织提供,主页:http://nutch.apache.org/

Nutch是目前最好的网络爬虫之一,Nutch分为内核和插件两个模块组成,内核控制整个爬取的逻辑,插件负责完成每个细节(与流程无关的细节)的实现。具体分工如下:

内核:控制爬虫按照 Inject -> Generator -> Fetch -> Parse -> Updatedb ( -> 提交索引(可选))的流程进行,而且这些流程都是利用map reduce在hadoop上实现的。

插件:实现爬虫的http请求、解析器、URL过滤器、索引等细节功能。

Nutch的内核提供了稳定的可在集群上运行的爬取机制(广度遍历),插件为爬虫提供了强大的扩展能力。


Crawler4j

Crawler4j由Yasser Ganjisaffar(微软bing的一位工程师)提供,项目主页: https://code.google.com/p/crawler4j/

用Crawler4j写爬虫,用户只需要指定两处:

     1) 爬虫的种子、线程数等配置

     2)覆盖WebCrawler类的visit(Page page)方法,对每个页面的自定义操作(抽取、存储)

这使得爬虫的二次开发大大简化,只需要定制两处,即可定制一个完成下载/精抽取功能的爬虫。python爬虫scrapy也是采用这种机制。


Nutch是被设计在hadoop上的,而且插件的调度以反射的形式实现,所以它的插件机制,并不如想象的那样灵活。写一个插件需要附带几个配置文件,并修改Nutch总配置文件。而且Nutch其实是为了搜索引擎定制的,所以NUTCH提供的挂载点,并不能做精抽取之类的业务提供很好的扩展。

Crwler4j虽然提供精简的用户接口,但是并没有一套插件机制,来定制自己的爬虫。例如用Crawler4j来爬取新浪微博,就需要修改源码,来完成对新浪微博的模拟登陆。



WebCollector


主页: https://github.com/CrawlScript/WebCollector

WebCollector使用了Nutch的爬取逻辑(分层广度遍历),Crawler4j的的用户接口(覆盖visit方法,定义用户操作),以及一套自己的插件机制,设计了一套爬虫内核。

WebCollector内核构架图:





CrawlDB: 任务数据库,爬虫的爬取任务(类似URL列表)是存放在CrawlDB中的,CrawlDB根据DbUpdater和Generator所选插件不同,可以有多种形式,如文件、redis、mysql、mongodb等。

Injector: 种子注入器,负责第一轮爬取时,向CrawlDB中提交爬取任务。在断点续爬的时候,不需要通过Injector向CrawlDB注入种子,因为CrawlDB中已有爬取任务。

Generator: 任务生成器,任务生成器从CrawlDB获取爬取任务,并进行过滤(正则、爬取间隔等),将任务提交给抓取器。

Fetcher: 抓取器,Fetcher是爬虫最核心的模块,Fetcher负责从Generator中获取爬取任务,用线程池来执行爬取任务,并对爬取的网页进行链接解析,将链接信息更新到CrawlDB中,作为下一轮的爬取任务。在网页被爬取成功/失败的时候,Fetcher会将网页和相关信息以消息的形式,发送到Handler的用户自定义模块,让用户自己处理网页内容(抽取、存储)。

DbUpdater: 任务更新器,用来更新任务的状态和加入新的任务,网页爬取成功后需要更新CrawlDB中的状态,对网页做解析,发现新的连接,也需要更新CrawlDB。

Handler: 消息发送/处理器,Fetcher利用Handler把网页信息打包,发送到用户自定义操作模块。

User Defined Operation: 用户自定义的对网页信息进行处理的模块,例如网页抽取、存储。爬虫二次开发主要就是自定义User Defined Operation这个模块。实际上User Defined Operation也是在Handler里定义的。

RequestFactory: Http请求生成器,通过RequestFactory来选择不同的插件,来生成Http请求,例如可以通过httpclient插件来使用httpclient作为爬虫的http请求,或者来使用可模拟登陆新浪微博的插件,来发送爬取新浪微博的http请求。

ParserFactory: 用来选择不同的链接分析器(插件)。爬虫之所以可以从一个网页开始,向多个网页不断地爬取,就是因为它在不断的解析已知网页中的链接,来发现新的未知网页,然后对新的网页进行同样的操作。


爬取逻辑:

WebCollector和Nutch一样,把爬虫的广度遍历拆分成了分层的操作。

第一层:爬取一个网页,http://www.apache.org/,解析网页,获取3个链接,将3个链接保存到CrawlDB中,设置状态为未爬取。同时将http://www.apache.org/的爬取状态设置为已爬取。结束第一轮。

第二层,找到CrawlDB中状态为未爬取的页面(第一层解析出来的3个链接),分别爬取,并解析网页,一共获得8个链接。和第一层操作一样,将解析出的链接放入CrawlDB,设置为未爬取,并将第二层爬取的三个页面,状态设置为已爬取。

第三层,找到CrawlDB中状态为未爬取的页面(第二层解析出来的8个链接).................


每一层都可以作为一个独立的任务去运行,所以可以将一个大型的广度遍历任务,拆分成一个一个小任务。爬虫里有个参数,设置爬取的层数,指的就是这个。


插件机制:

框架图中的 Injector、Generator、Request(由RequestFactory生成)、Parser(由ParserFactory生成)、DbUpdater、Response都是以插件实现的。制作插件往往只需要自定义一个实现相关接口的类,并在相关Factory内指定即可。

WebCollector内置了一套插件(cn.edu.hfut.dmic.webcollector.plugin.redis)。基于这套插件,可以把WebCollector的任务管理放到redis数据库上,这使得WebCollector可以爬取海量的数据(上亿级别)。


用户自定义操作:


对于用户来说,关注的更多的不是爬虫的爬取流程,而是对每个网页要进行什么样的操作。对网页进行抽取、保存还是其他操作,应该是由用户自定义的。

假设我们有个需求,要爬取《知乎》上的所有提问。对用户来说,只需要定义对知乎的提问如何抽取。


public class ZhihuCrawler extends BreadthCrawler{

    /*visit函数定制访问每个页面时所需进行的操作*/
    @Override
    public void visit(Page page) {
        String question_regex="^http://www.zhihu.com/question/[0-9]+";
        if(Pattern.matches(question_regex, page.getUrl())){
            System.out.println("正在抽取"+page.getUrl());
            /*抽取标题*/
            String title=page.getDoc().title();
            System.out.println(title);
            /*抽取提问内容*/
            String question=page.getDoc().select("div[id=zh-question-detail]").text();
            System.out.println(question);

        }
    }

    /*启动爬虫*/
    public static void main(String[] args) throws IOException{  
        ZhihuCrawler crawler=new ZhihuCrawler();
        crawler.addSeed("http://www.zhihu.com/question/21003086");
        crawler.addRegex("http://www.zhihu.com/.*");
        crawler.start(5);  
    }


}


覆盖BreadthCrawler类的visit方法,即可实现用户自定义操作,完全不用考虑爬虫的爬取逻辑。



WebCollector的设计主要来自于Nutch,相当于将Nutch抽象成了一个爬虫内核。

最后再次附上项目地址: https://github.com/CrawlScript/WebCollector






作者:AJAXHu 发表于2014-9-27 13:03:24 原文链接
阅读:22 评论:0 查看评论

相关 [webcollector 内核 解析] 推荐:

WebCollector内核解析—如何设计一个爬虫

- - CSDN博客推荐文章
本文利用 WebCollector内核的解析,来描述如何设计一个网络爬虫. 我们先来看看两个非常优秀爬虫的设计. Nutch由apache开源组织提供,主页:http://nutch.apache.org/. Nutch是目前最好的网络爬虫之一,Nutch分为内核和插件两个模块组成,内核控制整个爬取的逻辑,插件负责完成每个细节(与流程无关的细节)的实现.

JAVA爬虫Nutch、WebCollector的正则约束

- - CSDN博客互联网推荐文章
爬虫爬取时,需要约束爬取的范围. 基本所有的爬虫都是通过正则表达式来完成这个约束. 代表"http://www.xinhuanet.com/"后加任意个任意字符(可以是0个). 通过这个正则可以约束爬虫的爬取范围,但是这个正则并不是表示爬取新华网所有的网页. 新华网并不是只有www.xinhuanet.com这一个域名,还有很多子域名,类似:news.xinhuanet.com.

用WebCollector爬取新浪微博数据

- - CSDN博客互联网推荐文章
用WebCollector可以轻松爬取新浪微博的数据.. 首先需要一个能查看cookie的浏览器插件,推荐使用 firefox浏览器+firebug(插件).. 1.用浏览器打开 http://weibo.cn/pub/   这是新浪微博面对手机用户的一个入口.建议不要使用自己的账号来做爬虫.之所以选择weibo.cn来爬去,是因为这个手机版的限制较少,但是weibo.cn的账号密码都是以明文传输,所以为了防止盗号,建议新申请账号进行爬取..

Linux 内核优化

- - CSDN博客系统运维推荐文章
声明:本文档来自互联网整理部份加自已实验部份所得:. TCP 服务器 <---> 客户端通信状态.           ACK--------------->                                          建立连接.                    <---------------未回复.

JVM内核参数说明

- - 编程语言 - ITeye博客
java虽然是自动回收内存,但是应用程序,尤其服务器程序最好根据业务情况指明内存分配限制. 表示JVM Heap(堆内存)最小尺寸128MB,初始分配. 表示JVM Heap(堆内存)最大允许的尺寸256MB,按需分配. 说明:如果-Xmx不指定或者指定偏小,应用可能会导致java.lang.OutOfMemory错误,此错误来自JVM不是Throwable的,无法用try...catch捕捉.

常见浏览器内核

- - Web前端 - ITeye博客
一、Trident内核代表产品Internet Explorer,又称其为IE内核. Trident(又称为MSHTML),是微软开发的一种排版引擎. 使用Trident渲染引擎的浏览器包括:IE、傲游、世界之窗浏览器、Avant、腾讯TT、Netscape 8、NetCaptor、Sleipnir、GOSURF、GreenBrowser和KKman等.

解析DynamoDB

- - 技术改变世界 创新驱动中国 - 《程序员》官网
DynamoDB是Amazon最新发布的NoSQL产品. 本文在介绍DynamoDB特性的基础上,将其与SimpleDB、Cassandra和MongoDB进行了分析和比较. 在NoSQL概念日益火爆的今天,市场上又增加了一个重量级的NoSQL产品—DynamoDB,它是Amazon AWS于2012年1月18日发布的.

xml sax解析

- - 移动开发 - ITeye博客
最近一直在做接口,主要用对xml的解析用的是sax,下面我对sax的几种写法做了一个测试:. System.out.println("耗时:"+(end-start));. System.out.println("当前 Java 虚拟机中的使用内存量:" + (freeMemory01-freeMemory02) + " 字节");.

mysql explain 解析

- - SQL - 编程语言 - ITeye博客
Mysql Explain 详解. 例如: explain select * from t3 where id=3952602;. 二.explain输出解释. | id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |.

java解析APK

- - Linux - 操作系统 - ITeye博客
1、结合安卓提供apktool工具,用java执行cmd解析命令获取apk信息. 2、利用相关jar包里的集成方法解析apk. 这里只给出第二种方法,因为第一种方法在linux服务器下会出现不在控制范围之内的结果. // 将解压文件对象转列举对象. // 获得名为AndroidManifest.xml的文件.