当前位置 博文首页 > 少年时未觉悟 ,觉悟时不再年少,还危机四伏!:Webmagic 任务 I
WebMagic 是一个简单灵活的 Java 爬虫框架,基于 WebMagic,可以快速开发出高效、易维护的爬虫应用。爬虫管理器使用 Task 的 uuid 属性来关联站点和 URL ,以达到对待采集的 URL 进行去重、避免重复采集的问题。
本文来分析 Spider 类设置爬虫任务编号、和 setScheduler
的顺序对爬虫任务的影响及使用注意事项。
Scheduler
是 WebMagic 中进行 URL 管理的组件,一般来说,Scheduler
包括两个作用:
WebMagic 内置了几个常用的 Scheduler
,项目开发中我们都是选用支持分布式部署的 RedisScheduler
,它用 Redis 保存抓取的 URL 信息,以 Task 的 UUID 为主键,可进行多台机器同时合作抓取。
分析 RedisScheduler
源码可以知道,为了实现管理 URL 和去重的目的,它会以任务的 UUID 为后缀存储三类信息到 Redis :
使用 Spider + RedisScheduler 的通用代码为:
Spider spider = Spider.create(pageProcessor);
spider.addUrl(url).setUUID(taskId)
.addPipeline(pipeline)
.setScheduler(new RedisScheduler(SpringUtil.getBean(JedisPool.class)))
.setExecutorService(threadPool);
return spider;
因为 RedisScheduler
是通过认为的 uuid 为 key 来存储爬虫中间数据的,根据源码可知,在设置了调度器队列后,调度器队列数据就跟此时的 uuid
绑定了:
/**
* set scheduler for Spider
*
* @param scheduler scheduler
* @return this
* @see Scheduler
* @since 0.2.1
*/
public Spider setScheduler(Scheduler scheduler) {
checkIfRunning();
Scheduler oldScheduler = this.scheduler;
this.scheduler = scheduler;
if (oldScheduler != null) {
Request request;
while ((request = oldScheduler.poll(this)) != null) {
this.scheduler.push(request, this);
}
}
return this;
}
设置调度队列时,它会将旧调度器队列中的请求数据添加到新调度队列中。
笔者在测试分布式爬虫的时候,在调用 Spider
的 setScheduler
后,希望能够分片爬取,就再次设置 Spider 的 uuid 为新值后,爬虫就会一秒中结束,下载页面数为 0 。为什么呢?
publicSpider setUUID(String uuid) {
this.uuid = uuid;
return this;
}
分析源码,可以看到 setUUID
仅仅重新设置了 id ,并不会更新 Scheduler
中的请求和 task
的关联关系。
因此需要注意:创建爬虫的流程应该遵守一定的顺序,先设置 uuid ,再设置 Scheduler
,一旦固定,就不应该再改变任务编号。
如果要修改任务编号,则也应该重新设置调度器队列更新该对应关系。
cs