1、框架整体结构介绍
如上设计图,整个爬虫设计是纯异步的,利用消息队列进行各个组件的解耦,若是只需要单机爬虫则不需要做任何额外的配置,默认使用了一个内存型的消息队列;若是想要实一个纯分布式爬虫,则需要引入一个消息队列即可,后面会详细介绍如何实现一个分布式爬虫。
2、爬虫的基本流程
下载数据(发送 HTTP 请求并获得返回的 resonse)
-> 解析返回的文本(可以是 text、json、html
) -> 存储解析到的数据,针对这三个主逻辑,我们可以再细下成以下模块。
3、Scheduler 调度器
用于对采集请求的去重、采集顺序控制,默认实现了广度优先和深度优先两种调度器。调度器可以采用不同的 Hash
去重器,通常使用默认的 HashSetDuplicateRemover
即可,若是采集量很大可以使用 BloomFilterDuplicateRemover
。若想要调度海量的请求或者有重启续跑这样的需求,则需要自行实现基于数据库(关系型数据库、Redis 等)的调度器。
4、下载代理器
下载代理器可以部署在不同的机器上,若是单机爬虫则是每个爬虫实例会启动一个单独的下载代理器。下载代理器负责接收需要下载的请求并使用对应的下载器(HttpClient
, Puppter
或者自定义实现的下载器)。
5、下载代理器注册服务
此服务仅用于接收下载代理器的注册、心跳,即便不启用起服务也并不会影响爬虫的使用。单机爬虫会默认启用一个内存型的注册服务。
6、统计服务
统计各个爬虫和下载代理器的运行状态,如爬虫总的请求数、成功的请求数等,下载代理器总的成功请求数、总的消耗时间等
7、请求供应接口
在很多场景下可能下载请求是可以提前知道或存在某个地方(可以是文件、数据库)
8、请求配置(Spider.ConfigureRequest)
一般情况下请求都可以自动构建好,但在某些特别情况下如加 sign
等,可以统一处理。
9、DataFlow数据流
数据流分两种,解析器和存储器。最极端情况是你不想搞那么复杂,解析和存储都自己在一个 DataFlow
中实现。一个爬虫可以有多个 DataFlow
,执行顺序按添加顺序,在任意一个 DataFlow 中抛出异常都会中断整个处理流程。
10、代理池
每个爬虫实例会启动一个代理后台服务,此后台服务定时从注册的 IProxySupplier
中获取新的代理,每个获得的新代理需要经过检测成功才会入到代理池。在配置文件中或者 Builder 创建时可以配置测试地址:ProxyTestUri
11、并发控制器
并发控制器以一定速度从 Scheduler
中获取请求并推到到消息队列中,这些请求会缓存在 RequestedQueue
中,这个队列是使用低开销的 HashedWheelTimer
实现的,若在一定时间内未收到下载代理器返回的消息,则认为是 Timeout 触发重试直到超过重试次数限制。