WebMagic框架
1.webmagic框架
webmagic框架是一个Java实现的爬虫框架,底层依然是HttpClient和jsoup
组件:
- downloader:下载器组件
- PageProcessor:页面解析组件(必须自定义)
- scheculer:访问队列组件
- pipeline:数据持久化组件(默认是输出到控制台)
2.入门程序
2.1创建工程
- 创建一个Maven工程
- 添加坐标
junit junit 3.8.1 test us.codecraft webmagic-core 0.9.0 us.codecraft webmagic-extension 0.9.0
2.2入门程序
1.创建PageProcess接口实现类
package org.example; import us.codecraft.webmagic.Page; import us.codecraft.webmagic.ResultItems; import us.codecraft.webmagic.Site; import us.codecraft.webmagic.Spider; import us.codecraft.webmagic.processor.PageProcessor; import us.codecraft.webmagic.selector.Html; /** * 实现分析的业务逻辑 */ public class MypageProcessor implements PageProcessor { /** * 页面分析 * * @param page 下载结果封装成Page对象 * 可以从page对象中获得下载的结果 */ @Override public void process(Page page) { Html html = page.getHtml(); String htmlStr = html.toString(); //把结果输出到控制台 // ResultItems resultItems = page.getResultItems(); // resultItems.put("html", htmlStr); page.putField("html", htmlStr); } /** * 返回一个Site对象 * Site就是站点的配置 * 返回默认配置使用Site.me创建一个Site对象 * * @return */ @Override public Site getSite() { return Site.me(); } public static void main(String[] args) { Spider.create(new MypageProcessor()) //设置起始的url .addUrl("http://www.itcast.cn") //启动爬虫 //run 是同步方法在当前线程中执行 //start 在新线程中执行爬虫 .run(); } }
2.在实现类中实现页面分析的业务逻辑
3.初始化爬虫
4.启动爬虫
5.结果
3.组件介绍
3.1Downloader
下载器组件,使用HttpClient实现
如果没有特殊需求不需要自定义,默认的组件就可以满足全部需求
自定义时需要实现Downloader接口
向PageProcess传递数据时,把结果封装成Page对象
3.2PageProcess(必须自定义)
页面分析的业务组件,页面分析的逻辑在其中实现
需要实现PageProcessor接口
3.2.1.Site
Site代表一个站点信息
可以设置抓取的频率
重试的次数
超时时间
如果没有特殊需求 直接使用默认配置即可
3.2.2Page
getHtml(): 返回抓取的结果
getResultItems(): 返回ResultItems对象, 向pipeline传递数据时使用
getTargetReqyests()、getTargetReqyest(): 向scheduler对象中添加url
3.2.3html(Selectable)
html也是一个Selectable对象
一个Selectable就可以表示一个dom节点
使用html解析页面三种方式:
1.使用原生jsoup方法进行解析
Document document = html.getDocument();
2.使用框架提供的css选择器
html.css("选择器")
html.$("选择器")
3.使用Xpath解析
3.2.4ResultItems
作用就是把解析的结果传递给pipeline
可以使用page对象的getResultItems()方法获取该对象
也可以直接使用putField方法将数据添加到ResultItems对象中
3.2.5Request
并不是Http请求的Request对象,就是把url封装成Request对象
可以添加一个 也可以添加多个
3.3pipeline(自定义频率高)
数据持久化组件
框架提供了三个实现,ConsolePipeline:向控制台输出 默认的
FilePipeline:向磁盘文件中输出
JsonFilePipeline: 保存Json格式的文件
也可以自定义pipeline:
需要实现pipeline接口。
package org.example; import us.codecraft.webmagic.Page; import us.codecraft.webmagic.Site; import us.codecraft.webmagic.Spider; import us.codecraft.webmagic.pipeline.ConsolePipeline; import us.codecraft.webmagic.pipeline.FilePipeline; import us.codecraft.webmagic.processor.PageProcessor; import us.codecraft.webmagic.selector.Html; import us.codecraft.webmagic.selector.Selectable; import java.util.List; /** * 获取黑马网站全部网页 */ public class FilePipelinePageProcessor implements PageProcessor { @Override public void process(Page page) { //访问黑马首页 Html html = page.getHtml(); //解析首页中所有的链接地址 // Selectable css = html.css("a", "href"); Selectable links = html.links(); List all = links.all(); //把链接地址添加到访问队列中 page.addTargetRequests(all); //把页面传递给pipeline 保存到磁盘 page.putField("html",html.get()); } @Override public Site getSite() { return PageProcessor.super.getSite(); } public static void main(String[] args) { FilePipeline filePipeline = new FilePipeline(); filePipeline.setPath("Z:\html"); //使用spider初始化爬虫 Spider.create(new FilePipelinePageProcessor()) //设置起始的url .addUrl("http://www.itheima.com") //设置使用的pipeline .addPipeline(new ConsolePipeline()) .addPipeline(filePipeline) //启动 .run(); } }
3.4Scheduler
访问url队列
1.默认使用的内存队列
url数据量大时会占用大量的内存
2.文件形式的队列
需要制定保存队列文档的文件路径和文件名
3.redis分布式队列
实现分布式爬虫时 大规模爬虫时使用
3.4.1url去重
webmagic框架中可以对url进行去重处理
1.默认使用HashSet进行去重
需要占用大量的内存
2.规模大时 应该是用redis去重
使用redis成本高,需要搭建集群
3.布隆过滤器去重
内存小,速度快,成本低
缺点是有可能误判,不能删除
3.4.2布隆过滤器的使用
1.添加guava的jar包
com.google.guava guava 16.0.1
public static void main(String[] args) { FilePipeline filePipeline = new FilePipeline(); filePipeline.setPath("Z:\html"); //创建一个Scheduler QueueScheduler scheduler = new QueueScheduler(); //指定队列使用布隆过滤器去重 //初始化一个布隆过滤器 参数就是容量 scheduler.setDuplicateRemover(new BloomFilterDuplicateRemover(10000000)); //使用spider初始化爬虫 Spider.create(new FilePipelinePageProcessor()) //设置起始的url .addUrl("http://www.itheima.com") //设置使用的pipeline .addPipeline(new ConsolePipeline()) .addPipeline(filePipeline) //设置使用的Scheduler对象 .setScheduler(scheduler) //启动 .run(); }
3.5Spider
工具类,可以初始化爬虫
在spider中配置各个组件
启动爬虫
4.页面解析
4.1jsoup
package org.example; import org.jsoup.nodes.Document; 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.selector.Html; public class MypageProcessor1 implements PageProcessor { @Override public void process(Page page) { //使用原生Jsoup的api解析页面 Html html = page.getHtml(); //得到一个jsoup的Document对象 Document document = html.getDocument(); String title = document.getElementsByTag("title").text(); //传递给pipeline page.putField("title", title); } @Override public Site getSite() { return PageProcessor.super.getSite(); } public static void main(String[] args) { Spider.create(new MypageProcessor1()) .addUrl("https://www.jd.com") .start(); } }
4.2css选择器解析
//使用css解析器解析页面 Selectable domTitle = html.$("title","text"); // String title1 = domTitle.toString(); String title2 = domTitle.get(); page.putField("title2",title2);
Selectable元素 两个方法 get()、toString() 都可以把结果转换为字符串
如果返回的是一个dom列表,那么只返回第一个元素
all()就可以得到列表
4.3Xpath解析
这个是webmagic框架中实现的
XPath 教程 (w3school.com.cn)
package org.example; import org.jsoup.nodes.Document; 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.selector.Html; import us.codecraft.webmagic.selector.Selectable; import java.util.List; public class MypageProcessor1 implements PageProcessor { @Override public void process(Page page) { //使用原生Jsoup的api解析页面 Html html = page.getHtml(); //得到一个jsoup的Document对象 Document document = html.getDocument(); String title = document.getElementsByTag("title").text(); //传递给pipeline page.putField("title", title); //使用css解析器解析页面 Selectable domTitle = html.$("title", "text"); // String title1 = domTitle.toString(); String title2 = domTitle.get(); page.putField("title2", title2); //选择一个节点列表 // 只返回第一个 String s = html.css("link", "href").get(); // 返回列表 List all = html.css("link", "href").all(); System.out.println(s); System.out.println(all); //使用Xpath进行解析 Selectable xpath = html.xpath("//*[@id=\"navitems-group1\"]/li[1]/a/text()"); String addr = xpath.get(); page.putField("addr", addr); } @Override public Site getSite() { return PageProcessor.super.getSite(); } public static void main(String[] args) { Spider.create(new MypageProcessor1()) .addUrl("https://www.jd.com") .start(); } }
还没有评论,来说两句吧...