Java爬虫框架WebMagic学习

一、认识WebMagic

简介:一款简单灵活的爬虫框架
官方中文文档: http://webmagic.io/docs/zh

1.总体架构

WebMagic的结构分为Downloader、PageProcessor、Scheduler、Pipeline四大组件。
在这里插入图片描述

1.1.四大组件

  1. Downloader:负责从互联网上下载页面,以便后续处理。
  2. PageProcessor:负责解析页面,抽取有用信息,以及发现新的链接。对于每个站点每个页面都不一样,是需要使用者定制的部分。
  3. Scheduler:负责管理待抓取的URL,以及一些去重的工作。WebMagic默认提供了JDK的内存队列来管理URL,并用集合来进行去重。也支持使用Redis进行分布式管理。
  4. Pipeline:负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。

1.2.数据流转的对象

  1. Page:从Downloader下载到的一个页面——可能是HTML,也可能是JSON或者其他文本格式的内容。
  2. ResultItems:相当于一个Map,它保存PageProcessor处理的结果,供Pipeline使用。它的API与Map很类似,值得注意的是它有一个字段skip,若设置为true,则不应被Pipeline处理。

二、WebMagic爬虫项目简单Demo

介绍:以爬取起点中文网为例[https://www.qidian.com/all]

1.网页分析

1).具体某一个作品的链接在这里插入图片描述
2.具体某一个作品的详情,书名,作者和章节等等在这里插入图片描述

2.代码实现

2.1.添加依赖

注:由于我的代码中有打印日志,故排除了WebMagic包自带的slf4j-log4j12日志包。
 <!--导入WebMagic相关依赖-->
       <dependency>
           <groupId>us.codecraft</groupId>
           <artifactId>webmagic-core</artifactId>
           <version>0.7.2</version>
           <exclusions>
               <exclusion>
                   <artifactId>slf4j-log4j12</artifactId>
                   <groupId>org.slf4j</groupId>
               </exclusion>
           </exclusions>
       </dependency>
       <dependency>
           <groupId>us.codecraft</groupId>
           <artifactId>webmagic-extension</artifactId>
           <version>0.7.2</version>
       </dependency>

2.2.实现PageProcessor

PageProcessor的定制分为三个部分,分别是爬虫的配置、页面元素的抽取和链接的发现。
site:抓取网站的相关配置,包括编码、抓取间隔、重试次数等;
process:定制爬虫逻辑的核心接口,在这里编写抽取逻辑;根据正则表达式和XPath1语法抽取页面元素,以及深度挖掘url加入队列进行再次爬取。

package com.novelread.webmagic.processor;

import com.novelread.webmagic.pipeline.ConsolePipeline;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.pipeline.JsonFilePipeline;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Selectable;

/**
 * @author Administrator
 * @since 2018/11/28 14:20
 */
public class NovelRepoPageProcessor implements PageProcessor {

    final static Logger logger = LoggerFactory.getLogger(NovelRepoPageProcessor.class);

    /**
     * 主域名
     */
    public static final String BASE_URL = "http://www.qidian.com/";

    /**
     * 正则表达式\\. \\转义java中的\ \.转义正则中的.
     * 匹配作品URL 如:https://book.qidian.com/info/1010468795#Catalog
     * //book.qidian.com/info/1004608738
     */
    public static final String NOVEL_URL = "//book\\.qidian\\.com/info/\\d+";

    /**
     * 初始地址, 起点地址:中文网所有作品
     */
    public static final String START_URL = "https://www.qidian.com/all";

    /***
     * 部分一:抓取网站的相关配置,包括编码、抓取间隔、重试次数等
     */
    private Site site = Site.me().setRetryTimes(3).setSleepTime(1000)
            .addHeader("Accept-Encoding", "/")
            .setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36");

    /**
     *  process 是定制爬虫的逻辑的核心接口,在这里编写抽取逻辑
     *
     * @param page
     */
    @Override
    public void process(Page page) {
        // 部分二:定义如何抽取页面信息,并保存下来

        // 根据url判断页面类型
        if (page.getUrl().regex(START_URL).match()) {
            logger.info("作品总数XPath------>" + page.getHtml().xpath("//div[@id='sort-count']/div/span/text()").toString());

            // 爬取作品url加入队列
            Selectable links = page.getHtml().xpath("//div[@class=\"book-img-box\"]").links().regex(NOVEL_URL);
            page.addTargetRequests(page.getHtml().xpath("//div[@class=\"book-img-box\"]").links().regex(NOVEL_URL).all());

        } else {
            page.putField("name", page.getHtml().xpath("//div[@class=\"book-info\"]/h1/em/text()").toString());
            page.putField("author", page.getHtml().xpath("//div[@class=\"book-info\"]/h1/span/a/text()").toString());

        }
    }

    @Override
    public Site getSite() {
        return site;
    }
}

2.3.编写ConsolePipeline

Pileline是抽取结束后,进行处理的部分,它主要用于抽取结果的保存,也可以定制Pileline可以实现一些通用的功能。

package com.novelread.webmagic.pipeline;

import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;

import java.util.Map;

/**
* @author Administrator
* @since 2018/11/28 15:21
*/
public class ConsolePipeline implements Pipeline {

   /**
    * 将结果保存到控制台
    * @param resultItems
    * @param task
    */
   @Override
   public void process(ResultItems resultItems, Task task) {
       System.out.println("get page: " + resultItems.getRequest().getUrl());
       // 遍历所有结果,输出到控制台
       for (Map.Entry<String, Object> entry : resultItems.getAll().entrySet()) {
           System.out.println("爬取结果" + entry.getKey() + " :\t " + entry.getValue());
       }
   }
}

2.4.爬虫的配置、启动和终止

Spider:是爬虫启动的入口,使用一个PageProcessor创建一个Spider对象,然后使用run()进行启动。同时Spider的其他组件(Downloader、Scheduler、Pipeline)都可以通过set方法来进行设置。

/**
   * 使用Pipeline保存结果
   */
  public static void main(String[] args) {
      Spider.create(new NovelRepoPageProcessor())
              //从"https://www.qidian.com/all"开始抓
              .addUrl("https://www.qidian.com/all")
//                .addPipeline(new JsonFilePipeline("D:\\webmagic\\"))
              .addPipeline(new ConsolePipeline())
              //开启5个线程抓取
              .thread(5)
              //启动爬虫
              .run();
  }

2.5.运行结果

在这里插入图片描述

三、总结

本文只是根据文档写的一个简单的Demo实现简单爬虫,要想真正爬取自己想要的内容,还有一段很长的落要走。例如:对页面更详细分析,抽取内容;以及增量式抓取内容等等。
更多的参考
1.https://blog.csdn.net/weixin_39650971/article/details/79570038
2.https://blog.csdn.net/jibaole/article/details/52212886


  1. http://www.w3school.com.cn/xpath/xpath_syntax.asp ↩︎

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值