webmagic 源码解析

技术文章请注意时效!原理才是根本。

webmagic简介

webmagic是一个开源的Java爬虫框架,中文文档:http://webmagic.io/docs/zh

一个好的框架必然凝聚了领域知识。WebMagic的设计参考了业界最优秀的爬虫Scrapy,而实现则应用了HttpClient、Jsoup等Java世界最成熟的工具,目标就是做一个Java语言Web爬虫的教科书般的实现。 ​ 如果你是爬虫开发老手,那么WebMagic会非常容易上手,它几乎使用Java原生的开发方式,只不过提供了一些模块化的约束,封装一些繁琐的操作,并且提供了一些便捷的功能。 ​ 如果你是爬虫开发新手,那么使用并了解WebMagic会让你了解爬虫开发的常用模式、工具链、以及一些问题的处理方式。熟练使用之后,相信自己从头开发一个爬虫也不是什么难事。 ​ 因为这个目标,WebMagic的核心非常简单——在这里,功能性是要给简单性让步的。

虽然简单,但是完成所有功能,还是要花很多时间的。这里之分析webmagic-core。

webmagic架构图

webmagic有四个组件:Downloader、PageProcessor、Scheduler、Pipline。

三个数据对象:Request、Page、ResultItems。

spider的实例

webmagic线程模型

webmagic是典型的生产者消费者模式,spider实现了Runnable接口,作为生产线程,从Scheduler中取出request,提交给线程池CountableThreadPool运行。

1. spider的停止逻辑是:第一种情况,队列中没有新的url了,并且线程池中没有正在下载的队列,也就是说不会产生新的url了。如果设置了完成后退出,就会退出。第二种情况,队列中没有新的url了,但线程池还有下载队列,可能产生新的url,就在这里wait。等待线程池中线程下载完后signal。exitWhenComplete控制spider是否爬完就退出,如果不退出,spider会在队列空后等待,然后每隔一段时间唤醒,检查队列是否为空。添加新url也会唤醒。
2.spider在while循环中不断从队列中获得request,封装成Runnable交给线程池,如果队列很大,会不会封装很多的Runnable,从而造成内存不足呢?答案是不会的,作者封装了一个CountableThreadPool,spider初始化它的实例的时候,设置了一个threadNum,如果线程池满了,spider的生产线程要wait。

3.多个线程下载,spider 中只有一个 downloader 实例。查看 spider run () 中的 initComponent ()

原因是downloader使用PoolingHttpClientConnectionManager,默认就支持多线程,传入的poolSize就是spider中的threadNum,线程池的大小也是threadNum,所以没有问题。

webmagic组件

组件没什么可说的,就是各种设计模式。downloader组件封装了Apache HttpClient,考虑了ssl,cookie,redirect。可以借鉴一下。

发表评论

电子邮件地址不会被公开。 必填项已用*标注