一、资源
1.WebMagic介绍文档:http://webmagic.io/docs/zh/posts/ch6-custom-componenet/scheduler.html
2.依赖坐标:
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.5.2</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.5.2</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-selenium</artifactId>
<version>0.5.2</version>
</dependency>
二、抛出的问题
因为爬取的网页会源源不断更新数据,那么衍生出考虑自动增量爬取新数据的想法,并且防止数据重复爬取的问题。
三、解决的思路
1.Scheduler是WebMagic中进行URL管理的组件,默认使用的是QueueScheduler类:内存队列保存待抓取URL。
2.效仿爬虫框架作者实现的HashSetDuplicateRemover类:
private Set<String> urls = Sets.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
去重的方式是判断新url能不能正常加入到urls中,从而达到去重的目的。
3.自己实现DuplicateRemover接口,以适应具体的业务功能。
四、代码示例
1.实现DuplicateRemover接口,对同一地址实现自动增量爬取的功能
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.scheduler.component.DuplicateRemover;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class CustomDuplicateRemover implements DuplicateRemover {
private Set<String> urls = Collections.newSetFromMap(new ConcurrentHashMap());
public CustomDuplicateRemover() {
}
/**
* 重写去重规则
* @param request
* @param task
* @return
*/
@Override
public boolean isDuplicate(Request request, Task task) {
//不让框架排除当前网站,从而达到重复爬取当前网站的新增数据
if("http://www.luwenwang.com/bid/".equals(this.getUrl(request))){
return false;
}else {
//这里会将当前网站下的重复数据排除,所以达到爬取当前网站的新增数据的目的
return !this.urls.add(this.getUrl(request));
}
}
protected String getUrl(Request request) {
return request.getUrl();
}
@Override
public void resetDuplicateCheck(Task task) {
this.urls.clear();
}
@Override
public int getTotalRequestsCount(Task task) {
return this.urls.size();
}
}
2.调用实现类,并运行爬虫
public static void main(String[] args) throws Exception {
Spider spider = new Spider(new BlogPageProcessor());
spider.setScheduler(new QueueScheduler().setDuplicateRemover(
new CustomDuplicateRemover())
);
spider.addUrl(path).thread(10).run();
}