VSCrawler 是一个适合用作抓取的爬虫框架,在更多场景倾向于功能扩展性而牺牲使用简便性。这让 VSCrawler 非常强大,让他可以灵活的应对目标网站的反爬虫策略。
vscrawler 有挺多特点
1. 多用户登录,天生支持多用户登录,各个用户资源隔离维护。
2. 数据完整性保证,vs 保证即使爬虫宕机也会尽力序列化爬虫任务。
3. 任务调度,vs 目前不支持其他爬虫框架 schedular 角色的定制,不过 vs 本身的任务调度很完善,支持自定义消重规则、断点续爬、重试规则定制、重复抓取(在消重之上封装了可重入的特性)
4. 抽取器,vs 结合其他爬虫框架的实现,封装了整套抽取器体系。包括 CSS query && xpath(SipSoup,自 JsoupXpath 和 Xsoup 发展而来)、链式抽取(集合正则、xpath、css query、字符串处理函数、jsonpath)、字符串函数(基于表达式描述字符串逻辑,配合字符串函数表达式可以实现无编码支持字符串局部清洗处理)、表格处理(在 css 和 xpath 特征都不明显的 html 文档上面使用很方便)
5. 热发控制,vs 有一个热发配置文件,只有配置文件配置项修改了,vs 内部组件便可以感知到配置变更,同时执行对象更新操作。比如可以动态修改执行工作线程数量
6. 代理规则,vs 设计之前我便有一套完善的代理 ip 池系统(dungproxy),ip 池本身就有基于顺序惩罚模型的权值轮询队列,基于 ip 质量自动探测的方式调度 ip 使用顺序,实现了在免费的劣质 ip 源上架构稳定代理服务的系统。目前 vs 默认集成了 dungproxy,当然 ip 系统也是完全可以替换的
7.mq 模型的事件循环系统,vs 内置一个 EventLoop,用来实现各个组件低耦合的通信。对于 vs 的深度定制几乎不需要依靠各种生命周期回调,只需要订阅感兴趣的消息,然后就可以自动接收各种消息,同时也可以发送各种消息。
本次更新,主要完善了 vscrawler 对注解模式爬虫的支持,自此 vscrawler 也可以使用 java 注解描述爬虫规则了。
vsvcrawler 在实现注解爬虫的时候参考了 webmagic 和 gecco 两个爬虫框架,同时更好的集成了链式抽取,子 model 递归抽取,弱类型推测,以及提供了注解爬虫生命周期回调(用来弥补注解爬虫带来的扩展性制约问题),基于 package 扫描的 taskbean 注册等功能。
使用 demo:
- public class U5ProxyIpCrawler extends AbstractAutoProcessModel { @Xpath("/span[1]/li/text()") @Getter private String ip; @Xpath("//css('.port')::self()/text()") @Getter //type可以是一般的常用类型,框架会自动做类型转换,转换规则满足一般的弱语言规则,当不能强转时将会报错,如果你抓取的网站格式可能超过你预期范围,建议使用string来接收 private Integer port; @Xpath("/span[3]/li/allText()") //关于allText和text的区别,allText将会抽取子节点文本(对应Jsoup的text),text只会抽取当前节点文本(对应Jsoup的ownText),xpath语法细节请了解SipSoup这个项目 @Getter private String anonymous; public static void main(String[] args) { VSCrawlerBuilder .create() .setProcessor(AnnotationProcessorBuilder .create() .registryBean(U5ProxyIpCrawler.class) .build()) .setCrawlerName("u5ProxyCrawler") .build() .clearTask() .pushSeed("http://www.data5u.com/free/index.shtml") .run(); } }
或者使用对子 model 递归解析
- @AutoProcessor(seedPattern = "https://www\.meitulu\.com.*") public class Star extends AbstractAutoProcessModel { @Getter private String starName; @Getter //@Xpath("/css('.listtags_r')::self()/allText()") //如果只抽文本,则使用allText @Xpath("/css('.listtags_r')::self()/html()") private String desciption; @Xpath("/css('.listtags_l')::img/absUrl('src')") //absUrl可以处理相对路径和绝对路径问题,如果url是相对路径,absUrl会自动转化为绝对路径 @Getter private String headPicture; @Xpath(value = "//div[@class='boxs']/ul[@class='img']/li", elementType = Album.class) //由于泛型擦除可能,框架不能自动判断list内部的Album类型,所以需要elementType来制定,否则这里抽取得到的原始数据类型是element(Jsoup对象) @Getter private List<Album> albumList; @NewSeed @Xpath("//a/absUrl('href')") //@JSONField(serialize = false) private ListseedUrl; @Override protected void beforeAutoFetch() { super.beforeAutoFetch(); Matcher matcher = Pattern.compile("https://www\.meitulu\.com/t/([^/]+)").matcher(baseUrl); if (matcher.find()) { starName = matcher.group(1); } } }
注解爬虫详细文档稍后将会维护在项目主页:
项目 demo 都可以在 gitee 上找到: https://gitee.com/virjar/vscrawler/tree/master/vscrawler-samples
项目文档: http://vscrawler.virjar.com/
来源: http://www.phperz.com/article/17/1216/361830.html