webmagic 源码学习(2)

本文介绍WebMagic爬虫框架中的注解和正则组合抓取方法,包括ModelPageProcessor、ModelPipeline的工作原理及PageModelExtractor的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      webmagic的爬虫基本架构,其设计可以让人只需要实现PageProcessor中的process方法,完成列表页、详情页相应逻辑即可。而很多网站也许就只有简单的这两种页面的逻辑,webmagic还提供了更简单的表达两个页面解析逻辑的使用方法:一:注解;二: 正则组合。

  •     注解    

注解是Java里面用得多但写的不多的,我本人也没有概念,趁此机会学习一下Java注解。这篇博文讲得比较好 https://www.cnblogs.com/Qian123/p/5256084.html。 个人理解注解的功用是,作者设计出一套自己的表达逻辑、用以取代一定的语言上的功能,从而达到代码简洁的目的。

    本次源码都在webmagic-extension模块中,可以us.codecraft.webmagic.model开始,注解在annotation包中。

OOSpider主要成员是ModelPageProcessor,和 ModelPipeline ;都是处理注解的Model类,前者负责抓取时候解析,后者保存时候解析。ModelPageProcessor通过 addPageModel(Class clazz) ; ModelPipeline 则通过 PageModelPipeline<Class>两种方式关联和确定Model.class 。

public class GithubRepoTest {
    @Test
    public void test() {
        OOSpider.create(Site.me().setSleepTime(0)
                , new PageModelPipeline<GithubRepo>() {
            @Override
            public void process(GithubRepo o, Task task) {
                assertThat(o.getStar()).isEqualTo(86);
                assertThat(o.getFork()).isEqualTo(70);
            }
        }, GithubRepo.class).addUrl("https://github.com/code4craft/webmagic").setDownloader(new MockGithubDownloader()).test("https://github.com/code4craft/webmagic");
    }
}


1、ModelPageProcessor

     ModelPageProcessor存了个List<PageModelExtractor>;每个 注解类正是通过对应的一个 PageModelExtractor  来处理。核心方法void process(Page)时, 对每个PageModelExtractor, 根据它关联class的注解类型,

     1.1 extractLinks抽取helpUrl,经page.addTargetRequest的下一次继续抓取, 

   1.2 由 PageModelExtractor.process(page) 抽取页面元素obj, 元素经page.put(class.getCanonicalName, obj) 存入ResultItems,待pipeline后续保存。

2、ModelPipeline,

    OOSpider.modelPipeline  保存了一个 {class : PageModelPipeline<T>}的map  ,即代码清单的蓝色内部类。ModelPipeline在process时,对map中的每个PageModelPipeline: 从ResultItems里先根据上面(一.2)存好的obj ,进行 PageModelPipeline.process(obj) 。(此处我好奇,ModelPipeline是实现Pipeline接口的,把ResultItems当一个中转map用。能否反过来实现ModelPipeline<T>,Pipeline只是一个T=ResultItems的特例 呢?

而处理注解的核心还是PageModelExtractor,看它是怎么实现的。

3、PageModelExtractor

    3.1 PageModelExtractor.init(class)中首先取类注解,添加对应规则;然后提取成员注解,存入List<FieldExtractor>。 

   3.2 Object process(Page) 中,根据初始化过的规则和成员,调用processSingle方法。processSingle里首先class实例化Object o = clazz.newInstance();操作FieldExtractor抽取page上的值value。 通过 setField(o, FieldExtractor, value)添加到o对象;本方法正是上文 (一.2) 的具体实现。

    以上两步的实现反映了注解的设计,看起来要设计出让别人用起来方便的注解,还是需要一番功夫。

  •     正则组合

webmagic还提供了一种复合pattern抓取方式: CompositePageProcessor,CompositePipeline组合;在us.codecraft.webmagic.handler 中包中7个类。

       4.1  RequestMatcher 接口,核心  boolean match(Request page)   是否要处理请求request。

       4.2  PatternRequestMatcher implements RequestMatcher,     实现了match方法:正则匹配  request.getUrl

       4.3  SubPageProcessor extends RequestMatcher , 核心 processPage(Page page);                   留给自定义

       4.4  SubPipeline extends RequestMatcher , 核心  processResult(ResultItems resultItems, Task task);  留给自定义.

       4.5  PatternProcessor extends PatternRequestMatcher implements SubPipeline, SubPageProcessor; 初始化正则串 ,留出4.3、4.4两个接口。

    4.6 CompositePageProcessor implements PageProcessor。 主要结构List<SubPageProcessor>。已经实现了在void process(Page page) 时候,分别调用SubPageProcessor.processPage(page)

      4.7 CompositePipeline implements Pipeline。主要结构List<SubPipeline>, 已经实现了在void process(ResultItems) 时候分别调用subPipeline.processResult(resultItems)

      4.8 合在一起: us.codecraft.webmagic.example.PatternProcessorExample 。 实现只需要用正则来完成抽取任务的PatternProcessors  放入CompositePageProcessor 、CompositePipeline ,Spider.create方式启动即可。(这里一个PatternProcessor 对应一次完整的解析和保存,不能分开)


     读完webmagic源码之后可以说webmagic是麻雀虽小五脏俱全,webmagic-extension里的代码富含的设计理念更多一些,但core下的代码的设计更有美感,毕竟是直接从scrapy模仿过来的。不论如何webmagic不长,对编程进阶来说都是值得一阅的好源码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值