博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
给webmagic加上了注解支持
阅读量:6162 次
发布时间:2019-06-21

本文共 2450 字,大约阅读时间需要 8 分钟。

hot3.png

今天有个网友在博客回帖,能不能用注解来写一个爬虫?想了想,因为Javaer总习惯结果有个对象Model(我在自己用的时候也是这样),ResultItems的key-value形式难免会有点麻烦,何不将抽取和Model合为一体呢?好了!现在爬osc博客只有这点代码了!而且这个对象本身是可以继续使用的!

@TargetUrl("http://my.oschina.net/flashsword/blog/*")public class OschinaBlog { @ExtractBy("//title") private String title; @ExtractBy(value = "div.BlogContent",type = Fetcher.Type.Css) private String content; @ExtractBy(value = "//div[@class='BlogTags']/a/text()", multi = true) private List
tags;}

这里这个TargetUrl有两个意思:一个是符合这个url的交由这个Page处理,另一个是符合这样的url都会被抓取。怎么样?是不是很巧妙?另外为了方便,这里使用了类似正则的通配符形式(其实最终会编译成正则,只不过把"."转义成了"\.")。

考虑到一些更复杂的情况,例如:一个页面可能对应多个实体类(列表页视图),后面又做了一些更新,比如下面是一段抽取oschina问答的所有回答的代码:

@TargetUrl("http://www.oschina.net/question/\\d+_\\d+*")@HelpUrl("http://www.oschina.net/question/*")@ExtractBy(value = "//ul[@class='list']/li[@class='Answer']", multi = true)public class OschinaAnswer{ @ExtractBy("//img/@title") private String user; @ExtractBy("//div[@class='detail']") private String content; public static void main(String[] args) { OOSpider.create(Site.me().addStartUrl("http://www.oschina.net/question/567527_120597"), OschinaAnswer.class).run(); }}

咦?当自己写完这堆处理代码的时候,才发现webmagic完全变成了的一个注解版本。再看了一下Spiderman的,人家还内置了一套表达式引擎!

没关系,回到设计的初衷上来。Spiderman的设计是一个All-in-one的框架,提倡不写代码;而webmagic则是一个easy to build-in的框架,目标就是用代码实现爬虫,只不过少写点代码。不支持表达式引擎?没关系!复杂的逻辑,咱们可以写代码嘛!于是很简单的定义了一个AfterExtractor接口,在抽取完后,会调用这个接口:

@TargetUrl("http://my.oschina.net/flashsword/blog/*")public class OschinaBlog implements AfterExtractor { @ExtractBy("//title") private String title; @ExtractBy(value = "div.BlogContent", type = ExtractBy.Type.Css) private String content; @ExtractBy(value = "//div[@class='BlogTags']/a/text()", multi = true) private List
tags; @Override public void afterProcess(Page page) { System.out.println("title:\t"+title); System.out.println("content:\t"+content); System.out.println("tags:\t" + tags); } public static void main(String[] args) { OOSpider.create(Site.me().addStartUrl("http://my.oschina.net/flashsword/blog/145796"), OschinaBlog.class).run(); }}

public void afterProcess(Page page) 这个函数能做PageProcessor所有能做的事情。我想这段代码也不用咱说明了吧。个人还是比较满意的。

使用这个方式,结合,轻易实现了结果持久化到数据库的任务,代码:。

值得一提的是,以上代码都没有修改底层的核心模块划分,以前手写PageProcessor的方式依然是有效的。看来一个良好的前期规划是很有必要的!

代码目前在 annotation分支上,后续测试稳定后回合并到主干。

转载于:https://my.oschina.net/flashsword/blog/149307

你可能感兴趣的文章
Eclipsed的SVN插件不能识别之前工作空间的项目
查看>>
Linux 查看iptables状态-重启
查看>>
amazeui学习笔记一(开始使用2)--布局示例layouts
查看>>
c#中lock的使用(用于预约超出限额的流程)
查看>>
ODI基于源表时间戳字段获取增量数据
查看>>
并发容器之CopyOnWriteArrayList(转载)
查看>>
什么是AAC音频格式 AAC-LC 和 AAC-HE的区别是什么
查看>>
原创:goldengate从11.2升级到12.1.2
查看>>
Quartz
查看>>
正则表达式的语法规则
查看>>
C#一个关于委托和事件通俗易懂的例子
查看>>
类似于SVN的文档内容差异对比工具winmerge
查看>>
Cause: java.sql.SQLException: The user specified as a definer ('root'@'%') does not exist
查看>>
quratz线程
查看>>
execnet: rapid multi-Python deployment
查看>>
windows修改3389端口
查看>>
关于JavaScript词法
查看>>
FreeSwitch中的会议功能(4)
查看>>
MySQL中创建用户分配权限(到指定数据库或者指定数据库表中)
查看>>
AutoReleasePool 和 ARC 以及Garbage Collection
查看>>