高拓展性的Java多线程爬虫框架reptile(个人开源项目)

2019-10-29  本文已影响0人  谢朴欢

简介

Reptile是一个具有高拓展性的可支持单机与集群部署Java多线程爬虫框架,该框架可简化爬虫的开发流程。该框架各个组件高内聚松耦合的特性让用户可以对不同组件进行定制来满足不同的需求。

特性

架构

Reptile.png

Reptile作为爬虫主体可在主线程运行也可以异步运行,爬虫主要有四个核心组件:

四个组件之间的关系如架构图所示,它们之间的互相调用形成一个完整的工作流并在Workflow线程中运行,Reptile爬虫会根据配置的线程数量通过线程池创建指定数量的工作流线程并发执行工作流任务。

快速开始

使用Maven

  1. clone项目并构建发布到本地仓库
git clone git@github.com:xiepuhuan/reptile.git
cd reptile
mvn -Dmaven.test.skip=true
  1. 在项目中使用Maven引入对应的依赖
<dependency>
    <groupId>com.xiepuhuan</groupId>
    <artifactId>reptile</artifactId>
    <version>0.3</version>
</dependency>

使用方式

  1. 实现ResponseHandler接口,重写isSupporthandle方法。
    • isSupport方法根据reponseContext参数对象判断是否需要处理该响应,是则返回true,否则返回false
    • handle方法处理该响应,并将处理结果存储到result,如果从响应中有提取到要爬取的新请求则将其作为返回值返回。
    • 如果没有找到支持处理该响应的处理器则响应会被忽略。
  2. 实现Consumer接口,重写consume方法,执行对数据的消费,可在该方法中对响应处理结果进行持久化等操作,目前提供了ConsoleConsumer,JsonFileConsumer, MongoDBConsumer等实现,默认使用ConsoleConsumer

推荐

示例

单机部署

public class ZhihuPageHandler implements ResponseHandler {

    private static final String[] URLS = new String[] {
            "https://www.zhihu.com/api/v4/search_v3?t=general&q=java"
    };


    @Override
    public List<Request> handle(Response response, Result result) {
        Content content = response.getContent();
        JSONObject jsonObject = JSON.parseObject(content.getContent(), JSONObject.class);
        result.setResults(jsonObject.getInnerMap());

        JSONObject paging = jsonObject.getJSONObject("paging");

        if (!paging.getBoolean("is_end")) {
            List<Request> requests = new ArrayList<>();
            requests.add(new Request(paging.getString("next")));
            return requests;
        }
        return null;
    }

    @Override
    public boolean isSupport(Request request, Response response) {
        return true;
    }

    public static void main(String[] args) {

        // 构建Reptile爬虫配置类,
        ReptileConfig config = ReptileConfig.Builder.cutom()
                .setThreadCount(8)
                .appendResponseHandlers(new ZhihuPageHandler())
                .setDeploymentMode(DeploymentModeEnum.SINGLE)
                .setConsumer(new ConsoleConsumer())
                .build();
        // 根据reptile配置构建Reptile爬虫并添加爬去的URL
        Reptile reptile = Reptile.create(config).addUrls(URLS);
        // 启动爬虫
        reptile.start();
    }
}

分布式部署

分布式部署时,创建配置类时需要通过setDeploymentMode方法指定部署模式为DeploymentModeEnum.Distributed,并且需要通过setScheduler方法设置一个Redis队列调度器,可以使用RedisFIFOQueueScheduler作为实现。

public class ZhihuPageHandler implements ResponseHandler {

    private static final String[] URLS = new String[] {
            "https://www.zhihu.com/api/v4/search_v3?t=general&q=java"
    };

    @Override
    public List<Request> handle(Response response, Result result) {
        Content content = response.getContent();
        JSONObject jsonObject = JSON.parseObject(content.getContent(), JSONObject.class);
        result.setResults(jsonObject.getInnerMap());

        JSONObject paging = jsonObject.getJSONObject("paging");

        if (!paging.getBoolean("is_end")) {
            List<Request> requests = new ArrayList<>();
            requests.add(new Request(paging.getString("next")));
            return requests;
        }
        return null;
    }

    @Override
    public boolean isSupport(Request request, Response response) {
        return true;
    }

    public static void main(String[] args) {
            
            // 构建Redis队列调度器
            Scheduler scheduler = RedisFIFOQueueScheduler.Builder.custom()
                    .setRedisConfig(RedisConfig.DEFAULT_REDIS_CONFIG)
                    .setRequestFilter(RedisBloomRequestFilter.Builder.create())
                    .build();
            // 构建数据消费者
            Consumer consumer = new MongoDBConsumer(MongoDBConfig.DEFAULT_MONGODB_CONFIG);
    
            // 构建Reptile爬虫配置类
            ReptileConfig config = ReptileConfig.Builder.cutom()
                    .setThreadCount(8)
                    .appendResponseHandlers(new ZhihuPageHandler())
                    .setDeploymentMode(DeploymentModeEnum.Distributed)
                    .setScheduler(scheduler)
                    .setConsumer(consumer)
                    .build();
            // 根据reptile配置构建Reptile爬虫并添加爬去的URL
            Reptile reptile = Reptile.create(config).addUrls(URLS);
            // 启动爬虫
            reptile.start();
        }
}
上一篇 下一篇

猜你喜欢

热点阅读