webmagic保存html页面,Java爬虫第11课:webmagic中URL保存与去重

在解析页面的时候,很可能会解析出相同的url地址(例如商品标题和商品图片超链接,而且url一样),如果不进行处理,同样的url会解析处理多次,浪费资源。所以我们需要有一个url去重的功能。

20200716151513.png

URL保存

WebMagic提供了Scheduler可以帮助我们解决以上问题。

Scheduler是WebMagic中进行URL管理的组件。一般来说,Scheduler包括两个作用:

1)对待抓取的URL队列进行管理。

2)对已抓取的URL进行去重。

WebMagic内置了几个常用的Scheduler。如果你只是在本地执行规模比较小的爬虫,那么基本无需定制Scheduler,但是了解一下已经提供的几个Scheduler还是有意义的。

20200716151933.png

DuplicateRemovedScheduler

抽象基类,提供一些模板方法,继承它可以实现自己的功能

QueueScheduler

使用内存队列保存待抓取URL

PriorityScheduler

使用带有优先级的内存队列保存待抓取URL,耗费内存较QueueScheduler更大,但是当设置了request.priority之后,只能使用PriorityScheduler才可使优先级生效

FileCacheQueueScheduler

使用文件保存抓取URL,可以在关闭程序并下次启动时,从之前抓取到的URL继续抓取,需指定路径,会建立.urls.txt和.cursor.txt两个文件

RedisScheduler(开发最常用)

使用Redis保存抓取队列,可进行多台机器同时合作抓取(分布式),需要安装并启动redis

URL去重

去重部分被单独抽象成了一个接口:DuplicateRemover,从而可以为同一个Scheduler选择不同的去重方式,以适应不同的需要,目前提供了两种去重方式。

20200716151954.png

HashSetDuplicateRemover

使用HashSet来进行去重,占用内存较大

BloomFilterDuplicateRemover

使用BloomFilter来进行去重,占用内存较小,但是可能漏抓页面。

RedisScheduler是使用Redis的set进行去重,其他的Scheduler默认都使用HashSetDuplicateRemover来进行去重。

如果要使用BloomFilter,必须要加入以下依赖:

us.codecraft

webmagic-core

0.7.3

us.codecraft

webmagic-extension

0.7.3

com.google.guava

guava

16.0

修改代码,添加布隆过滤器public static void main(String[] args) {

Spider.create(new JobProcessor())

//初始访问url地址

.addUrl("https://www.jd.com/moreSubject.aspx")

.addPipeline(new FilePipeline("D:/webmagic/"))

.setScheduler(new QueueScheduler()

.setDuplicateRemover(new BloomFilterDuplicateRemover(10000000))) //参数设置需要对多少条数据去重

.thread(1)//设置线程数

.run();

}

修改public void process(Page page)方法,添加一下代码//每次加入相同的url,测试去重

page.addTargetRequest("https://www.jd.com/news.html?id=36480");

打开布隆过滤器BloomFilterDuplicateRemover,在下图处打断点测试

20200716151835.png

完整代码:package com.jiagou1216.crawler.test;

import us.codecraft.webmagic.Page;

import us.codecraft.webmagic.Site;

import us.codecraft.webmagic.Spider;

import us.codecraft.webmagic.processor.PageProcessor;

import us.codecraft.webmagic.scheduler.BloomFilterDuplicateRemover;

import us.codecraft.webmagic.scheduler.QueueScheduler;

import us.codecraft.webmagic.scheduler.Scheduler;

/**

* @author 架构师小跟班

* @Description: https://www.jiagou1216.com

* @date 2020/7/16 15:38

*/

public class JobProcessor implements PageProcessor {

//解析页面

public void process(Page page) {

//解析返回的数据page,并且把解析的结果放到ResultItems中

//css选择器

page.putField("div", page.getHtml().css("div.mt h2").all());

//XPath

page.putField("div2", page.getHtml().xpath("//div[@id=news_div]/ul/li/div/a"));

//正则表达式

page.putField("div3", page.getHtml().css("div#news_div a").regex(".*江苏.*").all());

//处理结果API

page.putField("div4", page.getHtml().css("div#news_div a").regex(".*江苏.*").get());

page.putField("div5", page.getHtml().css("div#news_div a").regex(".*江苏.*").toString());

//获取链接

//page.addTargetRequests(page.getHtml().css("div#news_div").links().regex(".*9$").all());

//page.putField("url",page.getHtml().css("div.mt h1").all());

page.addTargetRequest("https://www.jd.com/news.html?id=37319");

page.addTargetRequest("https://www.jd.com/news.html?id=37319");

page.addTargetRequest("https://www.jd.com/news.html?id=37319");

}

private Site site = Site.me()

.setCharset("utf8")    //设置编码

.setTimeOut(10000)   //设置超时时间,单位是ms毫秒

.setRetrySleepTime(3000)  //设置重试的间隔时间

.setSleepTime(3);      //设置重试次数

public Site getSite() {

return site;

}

//主函数,执行爬虫

public static void main(String[] args) {

Spider spider = Spider.create(new JobProcessor())

.addUrl("https://www.jd.com/moreSubject.aspx")  //设置爬取数据的页面

//.addPipeline(new FilePipeline("C:\\Users\\tree\\Desktop\\result"))

.thread(5)

//设置布隆去重过滤器,指定最多对1000万数据进行去重操作

.setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000000)));

Scheduler scheduler = spider.getScheduler();

//执行爬虫

spider.run();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值