现在的位置: 首页 > 综合 > 正文

利用WebCollector爬虫内核定制自己的爬虫——任务生成器Generator

2018年04月10日 ⁄ 综合 ⁄ 共 2620字 ⁄ 字号 评论关闭

1.将WebCollector导入工程:

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

    下载:webcollector-版本号-bin.zip

    将解压后文件夹中的所有jar包添加到工程既可。


2.抓取任务生成器(Generator):

   一个爬虫在一次任务中需要抓取哪些网页,是由任务生成器决定的。由于抓取任务的需求多种多样,所以任务生成器也有不同的种类。但是所有的任务生成器都继承自Generator类:Generator类源码

    所有的任务生成器都要实现Generator类中的next()函数:

  public abstract CrawlDatum next();


CrawlDatum是WebCollector中表示爬取信息的单元。一个CrawlDatum对象存储了一个网页(或者文件)的url,爬取状态(是否爬取),以及最后一次爬取时间。

抓取任务需要读取CrawlDatum对象的信息,所以抓取任务生成器需要给抓取器提供CrawlDatum对象。抓取器是通过调用Generator中的next()函数,来获取抓取任务的。


 public static void main(String[] args) throws IOException{
        /*CollectionGenerator可以根据指定的url或者url列表生成任务*/
        CollectionGenerator generator=new CollectionGenerator();
        generator.addUrl("http://lucene.apache.org/core/");
        generator.addUrl("http://lucene.apache.org/core/documentation.html");
        generator.addUrl("http://abc.abc.abc.abc.abc/");
        
        CrawlDatum crawldatum=null;
        while((crawldatum=generator.next())!=null){
            System.out.println(crawldatum.url);
        }
  }


运行结果:

http://lucene.apache.org/core/

http://lucene.apache.org/core/documentation.html

http://abc.abc.abc.abc.abc/

为什么把爬取任务生成器设计成这种类似流式的模式,而不是一次性生成一张任务列表?有两个原因:

1)如果用户自定义的Generator,以MYSQL之类的数据库为数据源,在一次任务中生成10万条CrawlDatum,利用next()这种流式设计,可以不用一次性把10万条CrawlDatum信息从mysql全部读出。抓取器会陆续从Generator中获取CrawlDatum,同时执行抓取任务。不会因为一次性取过多的CrawlDatum,导致响应慢或者内存过大。

2)采用流式,可以做多层Generator嵌套,以“管道-过滤器”的模式来生成任务。通过多个自定义的过滤器,可以过滤不想生成的任务。下面详细介绍过滤器。


过滤器,也是继承Generator类的,所以多个过滤器嵌套,最终得到的还是Generator类,可以作为任务生成器。


public static void main(String[] args) throws IOException{
        /*CollectionGenerator可以根据指定的url或者url列表生成任务*/
        CollectionGenerator generator=new CollectionGenerator();
        generator.addUrl("http://lucene.apache.org/core/");
        generator.addUrl("http://lucene.apache.org/core/");
        generator.addUrl("http://abc.abc.abc.abc.abc/");
        
        /*UniqueFilter是唯一性过滤器,会过滤以及出现过的url*/
        UniqueFilter uniquefilter=new UniqueFilter(generator);
        
        
        CrawlDatum crawldatum=null;
        while((crawldatum=uniquefilter.next())!=null){
            System.out.println(crawldatum.url);
        }
                
}


运行结果:


http://lucene.apache.org/core/
http://abc.abc.abc.abc.abc/


我们可以看到,经过过滤器生成的URL中,没有重复的URL。

注意我们在这里是调用UniqueFilter对象的next()函数,而不是CollectionGenerator对象的next()函数。


过滤器可以叠加很多层,比如在BreadthCrawler类中:

private Generator getGenerator(){
          Generator generator = new StandardGenerator(crawl_path);
          generator=new UniqueFilter(new IntervalFilter(new URLRegexFilter(generator, regexs)));
          generator.setTaskname(taskname);
          return generator;
}


在StandardGenerator外层套了三层过滤器:

1)正则过滤器:URLRegexFilter

2 )  爬虫更新时间间隔过滤器:IntervalFilter 。可以设置爬虫多久更新一次,例如一个月更新一次。如果上次爬取到现在还没有超过指定时间,例如爬取间隔还没有到一个月,就会被过滤。

3 ) URL唯一性过滤器:UniqueFilter。遇到重复出现的URL,则过滤。


练习:

1.自己写一个过滤器,过滤掉非http协议的URL,例如过滤ftp://123.1.1.1

2.自己写一个Generator,产生10个随机CrawlDatum.


练习答案暂不给出,可加群或发邮件讨论问题:

QQ群:250108697

邮箱:1216853554@qq.com







抱歉!评论已关闭.