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将它们彼此组织起来。这四大组件对应爬虫生命周期中的下载、处理、管理和持久化等功能。下面是官方给的架构图:

webmagic核心设计和运行机制分析_第1张图片

四个组件

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运行机制

webmagic核心设计和运行机制分析_第2张图片

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

你可能感兴趣的:(webmagic,java)