WebMagic

Posted roadlandscape

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebMagic相关的知识,希望对你有一定的参考价值。

WebMagic是一款爬虫框架,其底层使用的是HttpClient和Jsoup,让我们能够更方便的开发爬虫。

  WebMagic的结构分为Downloader、PageProcessor、Scheduler、Pipeline四大组件,并由Spider将它们彼此组织起来。这四大组件对应爬虫生命周期中的下载、处理、管理和持久化等功能。WebMagic的设计参考了Scapy(Python的爬虫框架),但是实现方式更Java化一些。   而Spider则将这几个组件组织起来,让它们可以互相交互,流程化的执行,可以认为Spider是一个大的容器,它也是WebMagic逻辑的核心。

WebMagic的四个组件:

  1.Downloader

    负责从互联网上下载页面,以便后续处理。WebMagic默认使用了Apache HttpClient作为下载工具。

  2.PageProcessor

    负责解析页面,抽取有用信息,以及发现新的链接。WebMagic使用Jsoup作为html解析工具,并基于其开发了解析XPath的工具Xsoup。   在这四个组件中,PageProcessor对于每个站点每个页面都不一样,是需要使用者定制的部分。

  3.Scheduler

    负责管理待抓取的URL,以及一些去重的工作。WebMagic默认提供了JDK的内存队列来管理URL,并用集合来进行去重。也支持使用Redis进行分布式管理

  4.Pipeline

    负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。Pipeline定义了结果保存的方式,如果你要保存到指定数据库,则需要编写对应的Pipeline。对于一类需求一般只需编写一个Pipeline。

用于数据流转的对象:

  1. Request

    是对URL地址的一层封装,一个Request对应一个URL地址。它是PageProcessor与Downloader交互的载体,也是PageProcessor控制Downloader唯一方式。   除了URL本身外,它还包含一个Key-Value结构的字段extra。你可以在extra中保存一些特殊的属性,然后在其他地方读取,以完成不同的功能。例如附加上一个页面的一些信息等。   2. Page

    代表了从Downloader下载到的一个页面——可能是HTML,也可能是JSON或者其他文本格式的内容。Page是WebMagic抽取过程的核心对象,它提供一些方法可供抽取、结果保存等。

  3. ResultItems

    相当于一个Map,它保存PageProcessor处理的结果,供Pipeline使用。它的API与Map很类似,值得注意的是它有一个字段skip,若设置为true,则不应被Pipeline处理。

快速入门:

  1.创建工程,引入依赖

    注意:0.7.3版本对SSL的并不完全,如果是直接从Maven中央仓库下载依赖,在爬取只支持SSL v1.2的网站会有SSL的异常抛出。

      解决方案:1.等作者的0.7.4的版本发布  2.直接从github上下载最新的代码,安装到本地仓库

      也可以参考以下资料自己修复  https://github.com/code4craft/webmagic/issues/701

  2.加入日志配置文件 log4j.properties

    WebMagic使用slf4j-log4j12作为slf4j的实现。

  3.测试

public class JobProcessor implements PageProcessor {

    // 解析页面
    @Override
    public void process(Page page) {
        // 解析返回的数据page,并且把解析的结果放ResultItems中
        page.putField("div", page.getHtml().css("div#shortcut #ttbar-login a").all());
    }

    @Override
    public Site getSite() {
        return Site.me();
    }


    public static void main(String[] args) {
        Spider.create(new JobProcessor())
                .addUrl("https://www.jd.com/") // 设置爬取数据的页面
                .run(); // 执行
    }
}

WebMagic里主要使用了三种解析页面技术:XPath、正则表达式和CSS选择器。另外,对于JSON格式的内容,可使用JsonPath进行解析。

  1.XPath 详细使用教程 https://www.w3school.com.cn/xpath/index.asp

// XPath
page.putField("div2", page.getHtml().xpath("//div[@id=J_cate]/ul/li/a"));

  2. CSS选择器

    .css("div#shortcut")

    .css("div#shortcut", "text").toString() :获取指定元素的纯文本

  3.正则表达式

// 正则表达式
page.putField("div3", page.getHtml().css("div#shortcut #ttbar-login a").regex(".*注册.*").all());

抽取元素API:

  技术图片

     这部分抽取API返回的都是一个Selectable接口,意思是说,是支持链式调用的。

获取结果API:

  page.getHtml().css("ul").nodes();  获取ul下的所有节点

  技术图片

   当有多条数据的时候,使用get()和toString()都是获取第一条。

// 处理结果API
page.putField("div4", page.getHtml().css("div#shortcut #ttbar-login a").get());
page.putField("div5", page.getHtml().css("div#shortcut #ttbar-login a").toString());
page.putField("div6", page.getHtml().css("div#shortcut #ttbar-login a").all());

  获取链接,把链接放到待抓取的队列中

// 获取连接
// page.addTargetRequest("http://www.xingdali.com/");
page.addTargetRequests(page.getHtml().css("ul.wide > li").links().all());
page.putField("nav", page.getHtml().css("div.tx-title1 > strong").all());

使用Pipeline保存结果:

  WebMagic用于保存结果的组件叫做Pipeline。我们不做任何操作就可以看到“控制台输出结果”是通过一个内置的Pipeline完成的,它叫做ConsolePipeline。

  那么,如果想要把结果保存到文件中,怎么做呢?只需将Pipeline的实现换成"FilePipeline"就可以了。

public static void main(String[] args) {
    Spider.create(new JobProcessor())
            // .addUrl("https://www.jd.com/") // 设置爬取数据的页面
            .addUrl("http://www.xingdali.com/")
            .addPipeline(new FilePipeline("D:aaa"))
            .thread(5) // 设置多线程
            .run(); // 执行
}

WebMagic的配置、启动和终止:

  1.Spider

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

    技术图片

   2.Site

    Site.me()可以对请求进行一些配置,包括编码、抓取间隔、超时时间、重试次数等。

    技术图片

@Override
public Site getSite() {
    return Site.me()
            .setCharset("utf8")
            .setTimeOut(1000) // 设置超时时间 单位ms
            .setRetrySleepTime(10000) // 设置重试的间隔时间
            .setRetryTimes(3); // 设置失败的重试次数
}

Scheduler组件:

  Scheduler是WebMagic中进行URL管理的组件。一般来说,Scheduler包括两个作用: 1.对抓取的URL队列进行管理  2.对已抓取的URL进行去重。

  WebMagic内置了几个常用的Scheduler。如果你只是在本地执行规模比较小的爬虫,那么基本无需定制Scheduler,但是了解一下已经提供的几个Scheduler还是有意义的。

    技术图片

  去重部分被单独抽象成了一个接口:DuplicateRemover,从而可以为同一个Scheduler 选择不同的去重方式,以适应不同的需要,目前提供了两种去重方式。

    技术图片

    RedisScheduler 是使用 Redis 的 set 进行去重,其他的 Scheduler 默认都使用HashSetDuplicateRemover 来进行去重。
  如果要使用 BloomFilter,必须要加入以下依赖:

<!--WebMagic 对布隆过滤器的支持-->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>16.0</version>
</dependency>
public static void main(String[] args) {
    Spider spider = Spider.create(new JobProcessor())
            // .addUrl("https://www.jd.com/") // 设置爬取数据的页面
            .addUrl("http://www.xingdali.com/")
            .addPipeline(new FilePipeline("D:aaa"))
            .thread(5) // 设置多线程
            .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(1000000))); // 参数设置对多少条数据进行去重

    Scheduler scheduler = spider.getScheduler();

    spider.run();
}

  三种去重方式:
    HashSet
      使用 java 中的 HashSet 不能重复的特点去重。优点是容易理解。使用方便。
      缺点:占用内存大,性能较低。
    Redis 去重
      使用 Redis 的 set 进行去重。优点是速度快(Redis 本身速度就很快),而且去重不会占用爬虫服务器的资源(单独部署redis),可以处理更大数据量的数据爬取。
      缺点:需要准备 Redis 服务器,增加开发和使用成本。
    布隆过滤器(BloomFilter )
      使用布隆过滤器也可以实现去重。优点是占用的内存要比使用 HashSet要小的多,也适合大量数据的去重操作。
      缺点:有误判的可能。没有重复可能会判定重复,但是重复数据一定会判定重复。

以上是关于WebMagic的主要内容,如果未能解决你的问题,请参考以下文章

WebMagic-使用入门

Webmagic之使用Pipeline保存结果

使用注解编写WebMagic爬虫

使用webmagic搭建一个简单的爬虫

使用webmagic搭建一个简单的爬虫

webmagic学习-使用注解编写爬虫