高拓展性的Java多线程爬虫框架reptile(个人开源项目)
优采云 发布时间: 2020-05-07 08:03Reptile是一个具有高拓展性的可支持单机与集群布署Java多线程爬虫框架,该框架可简化爬虫的开发流程。该框架各个组件高内聚松耦合的特点使用户可以对不同组件进行订制来满足不同的需求。
Reptile.png
Reptile作为爬虫主体可在主线程运行也可以异步运行,爬虫主要有四个核心组件:
Downloader 执行恳求下载与解析响应ResponseHandler 由使用者提供实现来对响应处理,生成Result结果与新的爬取恳求RequestConsumer 来对处理的结果Result进行消费,例如持久化储存java单机爬虫框架,用户可自定义其具体实现
四个组件之间的关系如构架图所示,它们之间的相互调用产生一个完整的工作流并在Workflow线程中运行,Reptile爬虫会依照配置的线程数目通过线程池创建指定数目的工作流线程并发执行工作流任务。
clone项目并建立发布到本地库房
git clone git@github.com:xiepuhuan/reptile.git
cd reptile
mvn -Dmaven.test.skip=true
在项目中使用Maven引入对应的依赖
<dependency>
<groupId>com.xiepuhuan</groupId>
<artifactId>reptile</artifactId>
<version>0.3</version>
</dependency>
实现ResponseHandler插口,重写isSupport与handle技巧。实现Consumer插口java单机爬虫框架,重写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作为实现。