使用和定制Pipeline
Pileline是抽取结束后,进行处理的部分,它主要用于抽取结果的保存,也可以定制Pileline可以实现一些通用的功能。
一个爬虫可以同时定制多个Pipeline
Pipeline的接口定义如下:
public interface Pipeline {
// ResultItems保存了抽取结果,它是一个Map结构,
// 在page.putField(key,value)中保存的数据,可以通过ResultItems.get(key)获取
public void process(ResultItems resultItems, Task task);
}
这里拿一个核心包内的ConsolePipeline来说
package us.codecraft.webmagic.pipeline;
import java.util.Iterator;
import java.util.Map.Entry;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
public class ConsolePipeline implements Pipeline {
public ConsolePipeline() {
}
public void process(ResultItems resultItems, Task task) {
System.out.println("get page: " + resultItems.getRequest().getUrl());
Iterator var3 = resultItems.getAll().entrySet().iterator();
while(var3.hasNext()) {
Entry<String, Object> entry = (Entry)var3.next();
System.out.println((String)entry.getKey() + ":\t" + entry.getValue());
}
}
}
上面这个代码是核心包自带的一个控制台输出的Pipeline
WebMagic已经提供的几个Pipeline
WebMagic中已经提供了将结果输出到控制台、保存到文件和JSON格式保存的几个Pipeline:
类 | 说明 | 备注 |
---|---|---|
ConsolePipeline | 输出结果到控制台 | 抽取结果需要实现toString方法 |
FilePipeline | 保存结果到文件 | 抽取结果需要实现toString方法 |
JsonFilePipeline | JSON格式保存结果到文件 | |
ConsolePageModelPipeline | (注解模式)输出结果到控制台 | |
FilePageModelPipeline | (注解模式)保存结果到文件 | |
JsonFilePageModelPipeline | (注解模式)JSON格式保存结果到文件 | 想要持久化的字段需要有getter方法 |
添加Pipeline到爬虫
配置Spider
public static void main(String[] args) {
//创建爬虫解析页面
PageProcessor pageProcessor = new FirstWebmagic();
//创建爬虫
Spider spider = Spider.create(pageProcessor);
//给爬虫添加爬取地址
spider.addUrl("https://blog.csdn.net/qq_18604209/rss/list");
//启动一个线程
spider.thread(1);
//添加PipPipeline
spider.addPipeline(new ConsolePipeline());//核心包自带的一个控制台Pipeline
//启动爬虫
spider.run();
}
修改PageProcessor
我们把之前的代码稍微做一下修改
我们需要page.putField()方法来确定我们想要的东西
@Override
public void process(Page page) {
//抓取到的页面为一个page对象
Html html = page.getHtml();//我们从page里面获取Html信息
Selectable item = html.$("item");//获取item标签
Selectable title = item.$("title","text");//获取items标签的 title 中的文字
Selectable link = item.$("guid","text");//获取items标签的 guid 中的文字
title = title.replace("\\<!\\[CDATA\\[","");
title = title.replace("\\]>","");
List<String> titles = title.all();
List<String> links = link.all();
for (int i = 0; i < titles.size(); i++) {
page.putField(titles.get(i),links.get(i));
}
}
之后控制台输出的结果为
[原][Java爬虫-WebMagic]-03-解析Html源码]: https://blog.csdn.net/qq_18604209/article/details/104213572
[原][Java爬虫-WebMagic]-02-获取网页源码]: https://blog.csdn.net/qq_18604209/article/details/104208837
[原][Java爬虫-WebMagic]-01-初识爬虫框架WebMagic]: https://blog.csdn.net/qq_18604209/article/details/104208038
....
自定义Pipeline
首先我们创建一个类实现Pipeline接口
/** 保存结果类 **/
class MyPipeline implements Pipeline{
@Override
public void process(ResultItems resultItems, Task task) {
Map<String,Object> map = resultItems.getAll();
Set<String> keys = map.keySet();
Iterator<String> it = keys.iterator();
while (it.hasNext()){
String title = it.next();
String link = map.get(title).toString();
System.out.println("{标题:"+ title + "--链接地址:"+ link +"}");
}
}
}
之后在Spider中添加我们自定义的Pipeline
public static void main(String[] args) {
//创建爬虫解析页面
PageProcessor pageProcessor = new FirstWebmagic();
//创建爬虫
Spider spider = Spider.create(pageProcessor);
//给爬虫添加爬取地址
spider.addUrl("https://blog.csdn.net/qq_18604209/rss/list");
//启动一个线程
spider.thread(1);
//添加PipPipeline
spider.addPipeline(new MyPipeline());//自己定义的
//可以添加多个Pipeline
spider.addPipeline(new ConsolePipeline());//核心包自带的一个控制台Pipeline
//启动爬虫
spider.run();
}
之后的输出结果
{标题:[原][Java爬虫-WebMagic]-03-解析Html源码]--链接地址:https://blog.csdn.net/qq_18604209/article/details/104213572}
{标题:[原][Java爬虫-WebMagic]-02-获取网页源码]--链接地址:https://blog.csdn.net/qq_18604209/article/details/104208837}
...
[原][Java爬虫-WebMagic]-03-解析Html源码]: https://blog.csdn.net/qq_18604209/article/details/104213572
[原][Java爬虫-WebMagic]-02-获取网页源码]: https://blog.csdn.net/qq_18604209/article/details/104208837
...
这样两个Pipeline都有输出的结果了
一个完整的代码
import us.codecraft.webmagic.*;
import us.codecraft.webmagic.pipeline.ConsolePipeline;
import us.codecraft.webmagic.pipeline.Pipeline;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;
import us.codecraft.webmagic.selector.Selectable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class FirstWebmagic implements PageProcessor
@Override
public void process(Page page) {
//抓取到的页面为一个page对象
Html html = page.getHtml();//我们从page里面获取Html信息
Selectable item = html.$("item");//获取item标签
Selectable title = item.$("title","text");//获取items标签的 title 中的文字
Selectable link = item.$("guid","text");//获取items标签的 guid 中的文字
title = title.replace("\\<!\\[CDATA\\[","");
title = title.replace("\\]>","");
List<String> titles = title.all();
List<String> links = link.all();
for (int i = 0; i < titles.size(); i++) {
page.putField(titles.get(i),links.get(i));
}
}
@Override
public Site getSite() {
Site site = Site.me();//创建Site
site.setTimeOut(1000);//设置超时
site.setRetryTimes(3);//设置重试次数
site.setCharset("UTF-8");
return site;
}
public static void main(String[] args) {
//创建爬虫解析页面
PageProcessor pageProcessor = new FirstWebmagic();
//创建爬虫
Spider spider = Spider.create(pageProcessor);
//给爬虫添加爬取地址
spider.addUrl("https://blog.csdn.net/qq_18604209/rss/list");
//启动一个线程
spider.thread(1);
//添加PipPipeline
spider.addPipeline(new MyPipeline());
//可以添加多个Pipeline
spider.addPipeline(new ConsolePipeline());//核心包自带的一个控制台Pipeline
//启动爬虫
spider.run();
}
}
/** 保存结果类 **/
class MyPipeline implements Pipeline{
@Override
public void process(ResultItems resultItems, Task task) {
Map<String,Object> map = resultItems.getAll();
Set<String> keys = map.keySet();
Iterator<String> it = keys.iterator();
while (it.hasNext()){
String title = it.next();
String link = map.get(title).toString();
System.out.println("{标题:"+ title + "--链接地址:"+ link +"}");
}
}
}