目录
  1. 1. 爬虫框架WebMagic
    1. 1.1. 架构解析
    2. 1.2. WenMagic组件
    3. 1.3. API
      1. 1.3.1. Spider API
      2. 1.3.2. Site API
    4. 1.4. PageProcessor
      1. 1.4.1. 爬取页面全部内容
      2. 1.4.2. 爬取指定内容
      3. 1.4.3. 添加目标地址
      4. 1.4.4. 目标地址正则匹配
    5. 1.5. Pipeline
      1. 1.5.1. ConsolePipeline 控制台输出(省略)
      2. 1.5.2. FilePipeline 文件输出
      3. 1.5.3. JsonFilePipeline Json输出
      4. 1.5.4. Custom Pipeline 自定义输出
    6. 1.6. Scheduler
      1. 1.6.1. 内存队列
      2. 1.6.2. 文件队列
      3. 1.6.3. Redis队列
  2. 2. 十次方文章数据爬取
    1. 2.1. 准备工作
    2. 2.2. 创建Module
爬虫

爬虫框架WebMagic

十次方前端:
链接:https://pan.baidu.com/s/1hSwWbVaYX7-SIXcTcSl2_Q
提取码:jq4t
复制这段内容后打开百度网盘手机App,操作更方便哦

十次方后端:
链接:https://pan.baidu.com/s/1TMuShDenXf43HyUql6hbQQ
提取码:kz8j
复制这段内容后打开百度网盘手机App,操作更方便哦

参考链接:十次方人工智能笔记一:网络爬虫

架构解析

WebMagic的设计目标是尽量的模块化,并体现爬虫的功能特点。这部分提供非常简单、灵活的API,在基本不改变开发模式的情况下,编写一个爬虫。

WebMagic的结构分为DownloaderPageProcessorSchedulerPipeline四大组件,并由Spider将它们彼此组织起来。这四大组件对应爬虫生命周期中的下载、处理、管理和持久化等功能。而Spider则将这几个组件组织起来,让它们可以互相交互,流程化的执行,可以认为Spider是一个大的容器,它也是WebMagic逻辑的核心

image-20191202091453144

WenMagic组件

  • Downloader

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

  • PageProcesser

PageProcessor负责解析页面,抽取有用信息,以及发现新的链接。WebMagic使用Jsoup作为HTML解析工具,并基于其开发了解析XPath的工具Xsoup。

在这四个组件中,PageProcessor对于每个站点每个页面都不一样,是需要使用者定制的部分

  • Scheduler

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

  • Pipeline

Pipeline负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。

API

Spider API

同时Spider的其他组件(Downloader、Scheduler、Pipeline)都可以通过set方法来进行设置。

image-20191202091744290

Site API

image-20191202091840244

PageProcessor

爬取页面全部内容

需求:编写爬虫程序,爬取csdn中博客的内容 https://blog.csdn.net/

  1. 创建工程,引入依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xushuai</groupId>
    <artifactId>webmagic_demo</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>
    <dependency>
    <groupId>us.codecraft</groupId>
    <artifactId>webmagic-core</artifactId>
    <version>0.7.3</version>
    </dependency>
    <dependency>
    <groupId>us.codecraft</groupId>
    <artifactId>webmagic-extension</artifactId>
    <version>0.7.3</version>
    </dependency>
    </dependencies>
    </project>
  2. 实现页面爬取

    package com.xushuai.magic.spider;

    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.processor.PageProcessor;

    /**
    * Spider Class Demo
    */
    public class PageProcessorDemo1 implements PageProcessor {


    public void process(Page page) {
    System.out.println(page.getHtml().toString());
    }

    public Site getSite() {
    return Site.me().setSleepTime(100).setRetryTimes(3);
    }

    public static void main(String[] args) {
    Spider.create(new PageProcessorDemo1())
    // 添加爬取的主网站
    .addUrl("https://www.csdn.net/")
    .run();
    }
    }

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

Site用于定义站点本身的一些配置信息,例如编码、HTTP头、超时时间、重试策略等、代理等,都可以通过设置Site对象来进行配置。

爬取指定内容

使用xpath来抓去网页指定部分内容

page.getHtml().xpath("//*[@id=\"nav\"]/div/div/ul/li[5]/a");

添加目标地址

添加目标地址,将目标地址中所有的链接添加到待爬取列表

page.addTargetRequests(page.getHtml().links().all());

目标地址正则匹配

需求:只提取博客的文章详细页内容,并提取标题

page.addTargetRequests(page.getHtml()
.links().regex("https://blog.csdn.net/[a-z 0-9-]+/article/de

Pipeline

ConsolePipeline 控制台输出(省略)

FilePipeline 文件输出

public static void main(String[] args) {
Spider.create(new PageProcessorDemo1())
// 添加爬取的主网站
.addUrl("https://www.csdn.net/")
// 添加控制台输出管道
.addPipeline(new ConsolePipeline())
// 添加文件输出管道
.addPipeline(new FilePipeline("F:/data"))
.run();
}

JsonFilePipeline Json输出

public static void main(String[] args) {
Spider.create(new PageProcessorDemo1())
// 添加爬取的主网站
.addUrl("https://www.csdn.net/")
// 添加控制台输出管道
.addPipeline(new ConsolePipeline())
// 添加文件输出管道
.addPipeline(new FilePipeline("F:/data"))
// 添加Json输出管道
.addPipeline(new JsonFilePipeline("F:/json"))
.run();
}

Custom Pipeline 自定义输出

  • 编写自定义管道类
package com.xushuai.magic.pipeline;

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

/**
* 自定义输出管道
*/
public class CustomPipeline implements Pipeline {
public void process(ResultItems resultItems, Task task) {
System.out.println(resultItems.get("title"));
}
}
  • 添加自定义管道
public static void main(String[] args) {
Spider.create(new PageProcessorDemo1())
// 添加爬取的主网站
.addUrl("https://www.csdn.net/")
// 添加控制台输出管道
.addPipeline(new ConsolePipeline())
// 添加文件输出管道
.addPipeline(new FilePipeline("F:/data"))
// 添加Json输出管道
.addPipeline(new JsonFilePipeline("F:/json"))
// 添加自定义管道
.addPipeline(new CustomPipeline())
.run();
}

Scheduler

Scheduler(URL管理)最基本的功能是实现对已经爬取的URL进行标示。可以实现URL的增量去重

目前Scheduler主要有三种实现方式:

  • 内存队列:QueueScheduler
  • 文件队列:FileCacheQueueScheduler
  • Redis队列:RedisScheduler

内存队列

public static void main(String[] args) {
Spider.create(new PageProcessorDemo1())
// 添加爬取的主网站
.addUrl("https://www.csdn.net/")
// 添加内存队列
.setScheduler(new QueueScheduler())
.run();
}

文件队列

使用文件保存抓取URL,可以在关闭程序并下次启动时,从之前抓取到的URL继续抓取。

public static void main(String[] args) {
Spider.create(new PageProcessorDemo1())
// 添加爬取的主网站
.addUrl("https://www.csdn.net/")
// 添加文件队列
.setScheduler(new FileCacheQueueScheduler("F:/scheduler"))
.run();
}

Redis队列

使用Redis保存抓取队列,可进行多台机器同时合作抓取。

public static void main(String[] args) {
Spider.create(new PageProcessorDemo1())
// 添加爬取的主网站
.addUrl("https://www.csdn.net/")
// 添加Redis队列
.setScheduler(new RedisScheduler("192.168.136.104"))
.run();
}

十次方文章数据爬取

需求:每日某时间段从CSDN播客中爬取文档,存入文章数据库中。

准备工作

  1. CSDN中各个频道的地址

image-20191202093206235

  1. 向数据库tensquare_article中的tb_channel表中添加记录

应该加好了

创建Module

  1. pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>i_parent</artifactId>
<groupId>com.i</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>i_article_crawler</artifactId>

<dependencies>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-core</artifactId>
<version>0.7.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-extension</artifactId>
<version>0.7.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.i</groupId>
<artifactId>i_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

</project>
  1. application.yml

    server:
    port: 9014
    spring:
    application:
    name: i-article-crawler #指定服务名
    datasource:
    driverClassName: com.mysql.jdbc.Driver
    url: jdbc:mysql://**********:3306/article?characterEncoding=UTF8
    username: ******
    password: ******
    jpa:
    database: MySQL
    show-sql: true
    redis:
    host: *************
  2. 启动类

package com.i.articlecrawler;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import us.codecraft.webmagic.scheduler.RedisScheduler;
import util.IdWorker;

@SpringBootApplication
@EnableScheduling
public class ArticleCrawlerApplication {

public static void main(String[] args) {

SpringApplication.run(ArticleCrawlerApplication.class);
}

@Value("${spring.redis.host}")
private String redis_host;

@Bean
public IdWorker idWorker(){
return new IdWorker(1,1);
}

// 这里使用的是Redis Scheduler
// 使用Redis保存抓取队列,可进行多台机器同时合作抓取
@Bean
public RedisScheduler redisScheduler(){
return new RedisScheduler(redis_host);
}
}
  1. 文章实体类以及数据访问接口
文章作者: 桔子邮差
文章链接: http://yoursite.com/2019/11/26/%E7%88%AC%E8%99%AB/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 微木斋
打赏
  • 微信
  • 支付寶

评论