WebMagic框架

1.webmagic框架

        webmagic框架是一个Java实现的爬虫框架,底层依然是HttpClient和jsoup

        组件:

  1. downloader:下载器组件
  2. PageProcessor:页面解析组件(必须自定义)
  3. scheculer:访问队列组件
  4. pipeline:数据持久化组件(默认是输出到控制台)

2.入门程序

        2.1创建工程

  1. 创建一个Maven工程
  2. 添加坐标  
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>us.codecraft</groupId>
        <artifactId>webmagic-core</artifactId>
        <version>0.9.0</version>
    </dependency>
    <dependency>
        <groupId>us.codecraft</groupId>
        <artifactId>webmagic-extension</artifactId>
        <version>0.9.0</version>
    </dependency>
    

        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<String> 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包

        

<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>16.0.1</version>
        </dependency>

        

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<String> 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();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/445425.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

redis 性能优化一

目录 前言 尾延迟 前言 说到redis 性能优化&#xff0c;优化的目的是什么&#xff1f;提高响应&#xff0c;减少延迟。就要关注两点&#xff0c;一是尾延迟&#xff0c;二是Redis 的基线性能。只有指标&#xff0c;我们的优化&#xff0c;才有意义&#xff0c;才能做监控以及…

Java中常用的集合及方法(3)

1、List&#xff08;接上级--常用方法示例补充&#xff09; 1.4 常用的方法 1.4.2 LinkedList&#xff08;JDK8&#xff09; LinkedList是Java中一个实现了List接口和Deque接口的类&#xff0c;它采用链表结构存储数据&#xff0c;支持高效的插入和删除操作。 LinkedList中…

【C++】深度解剖多态

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是多态&#xff0c;熟练掌握多态的定义&a…

NIO学习总结(一)——简介、Channel、Buffer

相关代码地址&#xff1a;nio_demo_learn: nio学习相关代码 (gitee.com) 一、BIO、NIO和AIO 1.1 阻塞IO&#xff08;BIO&#xff09; BIO即同步阻塞IO&#xff0c;实现模型为一个连接就需要一个线程去处理。这种方式简单来说就是当有客户端来请求服务器时&#xff0c;服务器就…

分布式搜索elasticsearch

1.初识elasticsearch 1.1.了解ES 1.1.1.elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮助我们从海量数据中快速找到需要的内容 例如&#xff1a; 在GitHub搜索代码 在电商网站搜索商品 在百度搜索答案…

MySQL主从读写分离之Proxysql(openEuler版)

实验目的&#xff1a; 基于proxysql实现MySQL的主从读写分离。 实验过程&#xff1a; 前期准备&#xff1a; 一共有四台虚拟机&#xff0c;其中三台为配置好的一主两从虚拟机&#xff0c;还有一台干净的虚拟机用来配置proxysql。 主机名地址master192.168.27.137node1192.…

NGINX源码安装详细配置文档

NGINX源码安装详细配置文档 一、基础Linux指令 查看nginx进程是否启动&#xff1a;ps -ef | grep nginx 关闭防火墙&#xff1a;systemctl stop firewalld 开放80端口&#xff1a;firewall-cmd --zonepublic --add-port80/tcp --permanent 关闭80端口&#xff1a;firewall-cmd …

(C语言)strcpy与strcpy详解,与模拟实现

目录 1. strcpy strcpy模拟实现&#xff1a; 实现方法1&#xff1a; 实现方法2&#xff1a; 2. strcat strcat模拟实现&#xff1a; 1. strcpy 作用&#xff1a;完成字符串的复制。 头文件&#xff1a;<string.h> destination是字符串要复制到的地点&#xff0c;s…

redis持久化-rdb

redis持久化-rdb策略 redis持久化rdb策略触发时机自动触发手动触发bgsave redis持久化 &#x1f680;我们知道redis是将数据存储在内存当中的&#xff0c;通常使用来作为关系型数据库的缓存使用的&#xff0c;以缓解当大量请求到来时关系型数据库的压力。 &#x1f680;既然数…

[LeetCode][226]翻转二叉树

题目 226. 翻转二叉树 给你一棵二叉树的根节点 root&#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#x…

025—pandas 根多列判断不在其他列的数据

思路 是有两个相同结构的数据表&#xff0c;已知第二个表是第一个表的部分数据&#xff0c;需要以其中两列为单位&#xff0c;判断在第一个表中存在&#xff0c;在另外一个表中不存在的数据。 思路&#xff1a; 我们先将 df1 和 df2 的 x、y 列取出&#xff0c;组合为元组形成…

013 Linux_互斥

前言 本文将会向你介绍互斥的概念&#xff0c;如何加锁与解锁&#xff0c;互斥锁的底层原理是什么 线程ID及其地址空间布局 每个线程拥有独立的线程上下文&#xff1a;一个唯一的整数线程ID, 独立的栈和栈指针&#xff0c;程序计数器&#xff0c;通用的寄存器和条件码。 和其…

【Python】成功解决IndexError: list index out of range

【Python】成功解决IndexError: list index out of range &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订…

整除光棍(pta团体天梯练习题)模拟手算除法c++

这里所谓的“光棍”&#xff0c;并不是指单身汪啦~ 说的是全部由1组成的数字&#xff0c;比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如&#xff0c;111111就可以被13整除。 现在&#xff0c;你的程序要读入一个整数x&#xff0c;这个整数一定…

朴素贝叶斯 | 多分类问题

目录 一. 贝叶斯公式的推导二. 朴素贝叶斯1. 离散的朴素贝叶斯朴素贝叶斯导入示例 离散的朴素贝叶斯训练 2. 连续的朴素贝叶斯3. 伯努利朴素贝叶斯4. 多项式朴素贝叶斯4.1 Laplace平滑4.2 Lidstone平滑 三. 概率图模型1. 贝叶斯网络(Bayesian Network)1.1 全连接贝叶斯网络1.2 …

【Redis知识点总结】(二)——Redis高性能IO模型剖析

Redis知识点总结&#xff08;二&#xff09;——Redis高性能IO模型及其事件驱动框架剖析 IO多路复用传统的阻塞式IO同步非阻塞IOIO多路复用机制 Redis的IO模型Redis的事件驱动框架 IO多路复用 Redis的高性能的秘密&#xff0c;在于它底层使用了IO多路复用这种高性能的网络IO&a…

[java入门到精通] 18 字符流,编码表,对象流,其他流

今日目标 编码表 字符输出流 字符输入流 字符缓冲流 转换流 对象操作流 装饰模式 commons-iojar包 1 编码表 1.1 思考&#xff1a; 既然字节流可以操作所有文件&#xff0c;那么为什么还要学习字符流 &#xff1f; 如果使用字节流 , 把文本文件中的内容读取到内存时…

ODP(Open Data Plane)

1. 摘要 本文档旨在指导新的ODP应用程序开发人员。 有关ODP的更多详细信息&#xff0c;请参见 ODP 主页。 Overview of a system running ODP applications ODP是一份API规范&#xff0c;为高性能网络应用程序的实现提供平台独立性、自动硬件加速和CPU扩展。 本文档介绍如何充…

DHCP中继实验(思科)

华为设备参考&#xff1a;DHCP中继实验&#xff08;华为&#xff09; 一&#xff0c;技术简介 DHCP中继&#xff0c;可以实现在不同子网和物理网段之间处理和转发DHCP信息的功能。如果DHCP客户机与DHCP服务器在同一个物理网段&#xff0c;则客户机可以正确地获得动态分配的IP…

OS-Copilot:实现具有自我完善能力的通用计算机智能体

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ AI 缩小了人类间的知识和技术差距 论文标题&#xff1a;OS-Copilot: Towards Generalist Computer Agents with Self-Improvement 论文链接&#xff1a;https://arxiv.org/abs/2402.07456 项目主页&a…
最新文章