WebMagic介绍
WebMagic的结构分为Downloader、PageProcessor、Scheduler、Pipeline四大组件,并由Spider将它们彼此组织起来。这四大组件对应爬虫生命周期中的下载、处理、管理和持久化等功能。
Spider则将这几个组件组织起来,让它们可以互相交互,流程化的执行,可以认为Spider是一个大的容器,它也是WebMagic逻辑的核心。
WebMagic的使用
1.导入依赖
2.添加log4j.properties
3.自定义一个类实现PageProcessor接口
public class ProcessorTest implements PageProcessor{
@Override
public void process(Page page) {
page.putField("title",page.getHtml().css("head > title").all();
//添加任务队列的URL
page.addTargetRequests(page.getHtml().links().all());
}
private Site site =Site.me()
.setCharset("UTF-8") //编码
.setSleepTime(1) //抓取间隔时间
.setTimeOut(1000*2) //超时时间
.setRetrySleepTime(3000) //重试时间
.setRetryTimes(3); //重试次数
@Override
public Site getSite() {
return this.site;
}
public static void main(String[] args){
Spider.create(new ProcessorTest())
.addUrl(""https://www.jd.com/moreSubject.aspx"") //设置请求URL
//设置输出信息到本地磁盘目录;默认ConsolePipeline,表示输出到控制台
.thread(5) //设置有5条线程处理
.addPipeline(new MyPipiline()) //设置自定义的管道来处理数据
.setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(100000))) //设置布隆过滤器
.run(); //发送请求
}
}
WebMagic选择器:
1.XPath选择器
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
/ 从根节点选取。
@ 选取属性。
page.getHtml().xpath("//div[@class=mt]/h1/text()")
选择class=mt的div标签下的h1标签内的text()
2.css选择器
page.getHtml().css("#testId").toString();
3.正则表达式
page.getHtml().regex("^a*$").toString();
4.获取所有的链接
page.getHtml().links().all();
WebMagic选择器的返回值Selectable的处理:
1.get() 返回一条String类型的结果 String link= html.links().get()
2.toString() 同get(),返回一条String类型的结果 String link= html.links().toString()
3.all() 返回所有抽取结果 List links= html.links().all()
通过process(Page page)收集到的数据,最终需要通过page.putField(String key,Object value)存到Pipeline中,然后自定义一个类实现Pipeline接口,通过resultItems.get(String key)获得存取到Pipeline中的数据;并需要Spider后面.addPipeline(new MyPipelene());
爬虫的分类
1.通用网络爬虫
抓取互联网上的所有数据,比如百度搜索
2.聚焦网络爬虫
只抓取指定类型数据,比如慢慢买网
3.增量式网络爬虫
只抓刚刚更新的数据
4.Deep Web 爬虫
抓取一些比如需要用户先登录才能访问的页面的数据
Scheduler
Scheduler的作用
1.对待抓取的URL队列进行管理。
2.对已抓取的URL进行去重。
scheduler对任务队列去重的原理:
1.HashSet
使用java中的HashSet不能重复的特点去重。优点是容易理解。使用方便。
缺点:占用内存大,性能较低。
2.Redis去重
使用Redis的set进行去重。优点是速度快(Redis本身速度就很快),而且去重不会占用爬虫服务器的资源,可以处理更大数据量的数据爬取。
缺点:需要准备Redis服务器,增加开发和使用成本。
3.布隆过滤器(BloomFilter)
使用布隆过滤器也可以实现去重。优点是占用的内存要比使用HashSet要小的多,也适合大量数据的去重操作。内存占用约为HashSet的十分之一
缺点:有误判的可能。没有重复可能会判定重复,但是重复数据一定会判定重复。
布隆过滤器去重原理:
布隆过滤器初始会定义一个位数组(二进制的数组),数组中的初始值全是0,并且数组有索引;当第一次保存一个数据,比如"hello",根据布隆过滤器内置的算法,计算出一组索引值,比如为1,2,3,然后将索引为1,2,3的位数组的值修改为1,表示已经存在;当如果再次保存另外一个数据,比如"world",计算出索引为3,4,5只要有一个索引重复了,布隆过滤器就认为这个数据已经存在
使用布隆过滤器需要导包
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0</version>
</dependency>
配置信息
WebMagic依赖:
<dependencies>
<!--WebMagic-->
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.7.3</version>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.7.3</version>
</dependency>
</dependencies>
注意:
0.7.3版本对SSL的并不完全,如果是直接从Maven中央仓库下载依赖,在爬取只支持SSLv1.2的网站会有SSL的异常抛出。
解决方案:
1.等作者的0.7.4的版本发布
2.直接从github上下载最新的代码,安装到本地仓库
也可以参考以下资料自己修复
https://github.com/code4craft/webmagic/issues/701
log4j.properties:
log4j.rootLogger=INFO,A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
Spider配置==
集成SpringBoot依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--SpringMVC-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--SpringData Jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--MySQL连接包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--WebMagic核心包-->
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.7.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--WebMagic扩展-->
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.7.3</version>
</dependency>
<!--WebMagic对布隆过滤器的支持-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0</version>
</dependency>
<!--工具包-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
</dependency>
</dependencies>