乐趣区

webmagic核心设计和运行机制分析

爬虫

通过程序代码将网页中我们需要的文本信息批量、自动保存下来。

自己如何实现

如果不用框架,完全我们自己手写实现爬虫的功能,思路流程应该是怎样的?

  1. 使用 http 类库下载一个起始 url 得到 html 字符串
  2. 解析 html 字符串得到我们需要的文本字符串
  3. 将第 2 步解析得到的文本字符串保存到数据库
  4. 如果起始 url 是博客文章列表页,我们还需要从 html 字符串中解析出每篇文章详细信息的 url 地址,再下载、解析文章详细信息 url 的网页 html 拿到文章的正文内容。这个过程肯定不能是手动的,第一想法是使用个内存阻塞队列来存储要爬取的 url,然后多线程 - 生产者消费者模式去解决。

WebMagic 框架就是做了上面流程的这些事,只需要我们自己写解析网页 html 字符串和保存到数据库的逻辑就行了(因为每个网页 html 字符串是不一样的),其他的都帮我们写好了。

WebMagic 的内部实现也是生产者 / 消费者模式(后续的源码分析篇会看到),四个组件根据名称就能知道其大概功能:Downloader 下载网页的,PageProcesser 解析 html 字符串的,Pipeline 写保存到数据库的逻辑,Scheduler 生产者 / 消费者模式中的阻塞队列。

WebMagic 核心设计

WebMagic 的结构分为 Downloader、PageProcessor、Scheduler、Pipeline 四大组件,并由 Spider 将它们彼此组织起来。这四大组件对应爬虫生命周期中的下载、处理、管理和持久化等功能。下面是官方给的架构图:

四个组件

Downloader

网页下载器。将一个 URL 地址对应的网页 HTML 文本下载到本地来。为了提高下载效率,WebMagic 在这一块设计成了多线程实现的方式。

可以继承 HttpClientDownloader,将下载失败的 URL 保存到 redis 中。

PageProcessor

页面处理器。对下载到本地的网页 HTML 文本进行分析,提取出我们需要的文本。

因为每个网页的内容是不同的,需要我们自定义处理逻辑。

Pipeline

持久化操作。将提取出的文本保存到数据库或文件中。

同样需要我们自定义保存到数据库的逻辑。

Scheduler

URL 管理器。所有 URL 都会存到 Scheduler 中,它相当于一个保存 URL 字符串的容器,内置了使用 set 进行 URL 去重功能。当我们需要爬取一个 URL 地址对应的网页时,就把这个 URL 推送到 Scheduler 中。下载器 Downloader 每次会从 Scheduler 中拉取出一个 URL 进行下载——典型的生产者 / 消费者模式。

因为需要分布式运行,所以需要我们自定义基于 redis 保存 URL 的 RedisScheduler 类,可以参考官方源码 webmagic-extension 包中 us.codecraft.webmagic.scheduler.RedisScheduler 实现。

执行引擎 Spider

将四个组件串起来进行整个爬取流程的核心组件,也是整个流程的入口,每个组件作为 Spider 的一个属性。

数据流转组件

Request

对请求的封装,也可以说是对 URL 的封装,内部还包含一个 extraMap, 用于传递一些额外的辅助信息

Page

对 Downloader 下载到的 HTML 页面的封装,从中可以获取到网页 html 文本,使用 xpath 解析 dom 提取出目标文本。

ResultItems

包裹从 PageProcessor 提取出来的数据,内部使用 Map 实现,用于 PageProcessor 和 Pipeline 之间的数据传递。

WebMagic 运行机制

  1. 创建 Spider 对象,设置自定义的 PageProcessor 和 Pipeline,如果自定义了 RedisScheduler 则设置,否则使用默认内存阻塞队列实现的 Scheduler,设置并发线程数,添加起始 url,启动爬虫 run()。
  2. 将封装起始 url 的 Request 对象推送到 Scheduler 的阻塞队列中。
  3. Downloader 从 Scheduler 中拉取 Request 进行下载,将得到的网页 html 文本封装成 Page 对象传递给 PageProcessor。
  4. PageProcessor 中自定义的解析逻辑从 html 文本中提取到目标文本,封装成 ResultItems 对象传递给 Pipeline。
  5. Pipeline 中自定义的持久化逻辑将目标文本保存到数据库。
  6. 如果 html 文本中有我们后续需要爬取的页面 url,将其提取出推送到 Scheduler,继续整个生产者 / 消费者循环。

小结

WebMagic 将爬取网页的流程分解成多个组件,封装其中不变的成分,内部使用生产者 / 消费者模式实现爬虫批量、自动爬取网页的特性。

退出移动版