基于Vert.x和RxJava 2构建通用的爬虫框架的示例

最近由于业务需要监控一些数据,虽然市面上有很多优秀的爬虫框架,但是我仍然打算从头开始实现一套完整的爬虫框架。

在技术选型上,我没有选择Spring来搭建项目,而是选择了更轻量级的Vert.x。一方面感觉Spring太重了,而Vert.x是一个基于JVM、轻量级、高性能的框架。它基于事件和异步,依托于全异步Java服务器Netty,并扩展了很多其他特性。

github地址:https://github.com/fengzhizi715/NetDiscovery

一. 爬虫框架的功能

爬虫框架包含爬虫引擎(SpiderEngine)和爬虫(Spider)。SpiderEngine可以管理多个Spider。

1.1 Spider

在Spider中,主要包含几个组件:downloader、queue、parser、pipeline以及代理池IP(proxypool),代理池是一个单独的项目,我前段时间写的,在使用爬虫框架时经常需要切换代理IP,所以把它引入进来。

proxypool地址:https://github.com/fengzhizi715/ProxyPool

其余四个组件都是接口,在爬虫框架中内置了一些实现,例如内置了多个下载器(downloader)包括vertx的webclient、http client、okhttp3、selenium实现的下载器。开发者可以根据自身情况来选择使用或者自己开发全新的downloader。

Downloader的download方法会返回一个Maybe<Response>。

package com.cv4j.netdiscovery.core.downloader;
import com.cv4j.netdiscovery.core.domain.Request;
import com.cv4j.netdiscovery.core.domain.Response;
import io.reactivex.Maybe;

/**
 * Created by tony on 2017/12/23.
 */
public interface Downloader {
  Maybe<Response> download(Request request);
  void close();
}

在Spider中,通过Maybe<Response>对象来实现后续的一系列的链式调用,比如将Response转换成Page对象,再对Page对象进行解析,Page解析完毕之后做一系列的pipeline操作。

         downloader.download(request)
              .observeOn(Schedulers.io())
              .map(new Function<Response, Page>() {

                @Override
                public Page apply(Response response) throws Exception {
                  Page page = new Page();
                  page.setHtml(new Html(response.getContent()));
                  page.setRequest(request);
                  page.setUrl(request.getUrl());
                  page.setStatusCode(response.getStatusCode());
                  return page;
                }
              })
              .map(new Function<Page, Page>() {

                @Override
                public Page apply(Page page) throws Exception {

                  if (parser != null) {

                    parser.process(page);
                  }

                  return page;
                }
              })
              .map(new Function<Page, Page>() {

                @Override
                public Page apply(Page page) throws Exception {

                  if (Preconditions.isNotBlank(pipelines)) {

                    pipelines.stream()
                        .forEach(pipeline -> pipeline.process(page.getResultItems()));
                  }

                  return page;
                }
              })
              .subscribe(new Consumer<Page>() {

                @Override
                public void accept(Page page) throws Exception {

                  log.info(page.getUrl());

                  if (request.getAfterRequest()!=null) {

                    request.getAfterRequest().process(page);
                  }
                }
              }, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                  log.error(throwable.getMessage());
                }
              });

在这里使用RxJava 2可以让整个爬虫框架看起来更加响应式:)

1.2 SpiderEngine

SpiderEngine可以包含多个Spider,可以通过addSpider()、createSpider()来将爬虫添加到SpiderEngine和创建新的Spider并添加到SpiderEngine。

在SpiderEngine中,如果调用了httpd(port)方法,还可以监控SpiderEngine中各个Spider。

1.2.1 获取某个爬虫的状态

http://localhost:{port}/netdiscovery/spider/{spiderName}

类型:GET

1.2.2 获取SpiderEngine中所有爬虫的状态

http://localhost:{port}/netdiscovery/spiders/

类型:GET

1.2.3 修改某个爬虫的状态

http://localhost:{port}/netdiscovery/spider/{spiderName}/status

类型:POST

参数说明:

{
  "status":2  //让爬虫暂停
}
status 作用
2 让爬虫暂停
3 让爬虫从暂停中恢复
4 让爬虫停止

使用框架的例子

创建一个SpiderEngine,然后创建三个Spider,每个爬虫每隔一定的时间去爬取一个页面。

    SpiderEngine engine = SpiderEngine.create();
    Spider spider = Spider.create()
        .name("tony1")
        .repeatRequest(10000,"http://www.163.com")
        .initialDelay(10000);

    engine.addSpider(spider);
    Spider spider2 = Spider.create()
        .name("tony2")
        .repeatRequest(10000,"http://www.baidu.com")
        .initialDelay(10000);

    engine.addSpider(spider2);
    Spider spider3 = Spider.create()
        .name("tony3")
        .repeatRequest(10000,"http://www.126.com")
        .initialDelay(10000);
    engine.addSpider(spider3);
    engine.httpd(8080);
    engine.run();

上述程序运行一段时间之后,在浏览器中输入:http://localhost:8080/netdiscovery/spiders

我们能看到三个爬虫运行的结果。

将json格式化一下

{
  "code": 200,
  "data": [{
    "downloaderType": "VertxDownloader",
    "leftRequestSize": 0,
    "queueType": "DefaultQueue",
    "spiderName": "tony2",
    "spiderStatus": 1,
    "totalRequestSize": 7
  }, {
    "downloaderType": "VertxDownloader",
    "leftRequestSize": 0,
    "queueType": "DefaultQueue",
    "spiderName": "tony3",
    "spiderStatus": 1,
    "totalRequestSize": 7
  }, {
    "downloaderType": "VertxDownloader",
    "leftRequestSize": 0,
    "queueType": "DefaultQueue",
    "spiderName": "tony1",
    "spiderStatus": 1,
    "totalRequestSize": 7
  }],
  "message": "success"
}

案例

最近比较关注区块链,因此做了一个程序来实时抓取三种数字货币的价格,可以通过“询问”公众号的方式来获取最新的价格。

目前该程序已经上线,可以通过询问我的公众号,来实时获取这几种数字货币的最新价格。

TODO

  1. 增加对登录验证码的识别
  2. 增加elasticsearch的支持

总结

这个爬虫框架才刚刚起步,我也参考了很多优秀的爬虫框架。未来我会在框架中考虑增加通过截屏图片来分析图片中的数据。甚至会结合cv4j框架。过年前,在爬虫框架中会优先实现对登录验证码的识别。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • 基于RxJava2实现的简单图片爬虫的方法
  • java网络爬虫连接超时解决实例代码
  • Java爬虫实现爬取京东上的手机搜索页面 HttpCliient+Jsoup
  • java实现一个简单的网络爬虫代码示例
  • 分享一个简单的java爬虫框架
  • JAVA超级简单的爬虫实例讲解
  • hadoop中实现java网络爬虫(示例讲解)
  • JAVA爬虫实现自动登录淘宝
(0)

相关推荐

  • Java爬虫实现爬取京东上的手机搜索页面 HttpCliient+Jsoup

    1.需求及配置 需求:爬取京东手机搜索页面的信息,记录各手机的名称,价格,评论数等,形成一个可用于实际分析的数据表格. 使用Maven项目,log4j记录日志,日志仅导出到控制台. Maven依赖如下(pom.xml) <dependencies> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId>

  • JAVA爬虫实现自动登录淘宝

    目的 想通过JAVA代码实现淘宝网的自动登录,通过获取设置的登录信息自动填写并提交.目前这个代码是小编测试过的,可以通过,后期不知道淘宝会不会有相应的封堵策略. 代码分享: package util; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.fi

  • hadoop中实现java网络爬虫(示例讲解)

    这一篇网络爬虫的实现就要联系上大数据了.在前两篇java实现网络爬虫和heritrix实现网络爬虫的基础上,这一次是要完整的做一次数据的收集.数据上传.数据分析.数据结果读取.数据可视化. 需要用到 Cygwin:一个在windows平台上运行的类UNIX模拟环境,直接网上搜索下载,并且安装: Hadoop:配置Hadoop环境,实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS,用来将收集的数据直接上传保存到HDFS,然后用MapReduce

  • 基于RxJava2实现的简单图片爬虫的方法

    今年十月份以来,跟朋友尝试导入一些图片到tensorflow来生成模型,这就需要大量的图片.刚开始我只写了一个简单的HttpClient程序来抓取图片,后来为了通用性索性写一个简单的图片爬虫程序.它可以用于抓取单张图片.多张图片.某个网页下的所有图片.多个网页下的所有图片. github地址:https://github.com/fengzhizi715/PicCrawler 这个爬虫使用了HttpClient.RxJava2以及Java 8的一些特性.它支持一些简单的定制,比如定制User-A

  • JAVA超级简单的爬虫实例讲解

    爬取整个页面的数据,并进行有效的提取信息,注释都有就不废话了: public class Reptile { public static void main(String[] args) { String url1=""; //传入你所要爬取的页面地址 InputStream is=null; //创建输入流用于读取流 BufferedReader br=null; //包装流,加快读取速度 StringBuffer html=new StringBuffer(); //用来保存读取页

  • java网络爬虫连接超时解决实例代码

    本文研究的主要是java网络爬虫连接超时的问题,具体如下. 在网络爬虫中,经常会遇到如下报错.即连接超时.针对此问题,一般解决思路为:将连接时间.请求时间设置长一下.如果出现连接超时的情况,则在重新请求[设置重新请求次数]. Exception in thread "main" java.net.ConnectException: Connection timed out: connect 下面的代码便是使用httpclient解决连接超时的样例程序.直接上程序. package da

  • 分享一个简单的java爬虫框架

    反复给网站编写不同的爬虫逻辑太麻烦了,自己实现了一个小框架 可以自定义的部分有: 请求方式(默认为Getuser-agent为谷歌浏览器的设置),可以通过实现RequestSet接口来自定义请求方式 储存方式(默认储存在f盘的html文件夹下),可以通过SaveUtil接口来自定义保存方式 需要保存的资源(默认为整个html页面) 筛选方式(默认所有url都符合要求),通过实现ResourseChooser接口来自定义需要保存的url和资源页面 实现的部分有: html页面的下载方式,通过Htt

  • java实现一个简单的网络爬虫代码示例

    目前市面上流行的爬虫以python居多,简单了解之后,觉得简单的一些页面的爬虫,主要就是去解析目标页面(html).那么就在想,java有没有用户方便解析html页面呢?找到了一个jsoup包,一个非常方便解析html的工具呢. 使用方式也非常简单,引入jar包: <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.8.

  • 基于Vert.x和RxJava 2构建通用的爬虫框架的示例

    最近由于业务需要监控一些数据,虽然市面上有很多优秀的爬虫框架,但是我仍然打算从头开始实现一套完整的爬虫框架. 在技术选型上,我没有选择Spring来搭建项目,而是选择了更轻量级的Vert.x.一方面感觉Spring太重了,而Vert.x是一个基于JVM.轻量级.高性能的框架.它基于事件和异步,依托于全异步Java服务器Netty,并扩展了很多其他特性. github地址:https://github.com/fengzhizi715/NetDiscovery 一. 爬虫框架的功能 爬虫框架包含爬

  • 基于Java代码实现支付充值的通用流程

    废话不多说了,直接给大家贴java代码了. 具体代码如下所示: /*支付流程*/ /****Controller.java 代码如下:*/ @RequestMapping(value = "/paySubmit.htm", method = RequestMethod.POST) public ModelAndView paySubmit(HttpServletRequest request, HttpServletResponse response, @RequestParam Ma

  • 基于Apache Hudi在Google云构建数据湖平台的思路详解

    自从计算机出现以来,我们一直在尝试寻找计算机存储一些信息的方法,存储在计算机上的信息(也称为数据)有多种形式,数据变得如此重要,以至于信息现在已成为触手可及的商品.多年来数据以多种方式存储在计算机中,包括数据库.blob存储和其他方法,为了进行有效的业务分析,必须对现代应用程序创建的数据进行处理和分析,并且产生的数据量非常巨大!有效地存储数PB数据并拥有必要的工具来查询它以便使用它至关重要,只有这样对该数据的分析才能产生有意义的结果.大数据是一门处理分析方法.有条不紊地从中提取信息或以其他方式处

  • 打造通用的匀速运动框架(实例讲解)

    本文,是接着上 基于匀速运动的实例讲解(侧边栏,淡入淡出) 继续的,在这篇文章的最后,我们做了2个小实例:侧边栏与改变透明度的淡入淡出效果,本文我们把上文的animate函数,继续改造,让他变得更加的通用和强大: 1,支持多个物体的运动 2,同时运动 3,顺序运动 这三种运动方式也是jquery中animate函数支持的 一.animate函数中怎么区分变化不同的样式? 上文中,侧边栏效果 用的animate函数 改变的是left值 function animate(obj, target, s

  • Kotlin下Rxjava的基础用法及流式调用示例详解

    目录 前言 基础用法 fromXXX create interval & timer 指定线程 observeOn & subscribeOn Flowable 流式调用 背压 前言 万事开头难,写文章也是,现在越来越不知道开头怎么写了,所以在前言中,简单介绍下RxJava吧,第一次听说还是以前做Android开发的时候,那时候好多库中都使用了Rxjava,而在网络请求中,也有很多都是使用Rxjava去写,但自己却没怎么在项目中写过,而在搜索资料中发现,微信中搜rxjava时,最多介绍他的

  • 用 Composer构建自己的 PHP 框架之构建路由

    上一篇中我们已经建立了一个空的 Composer 项目,本篇将讲述如何构建路由. 久负盛名的 CodeIgniter 框架是很多人的 PHP 开发入门框架,同样也是我开始学习如何从头构建一个网站的框架.在 CI 中我学到了很多,其中对 MVC 的深入理解和对框架本质的理解对我的影响最大.从使用框架是为了提高开发效率的角度来看,框架的本质就是路由. 下面我们就开始自己来构建路由,先去 GitHub 搜一下:点此查看搜索结果 推荐https://github.com/NoahBuscher/Maca

  • python构建基础的爬虫教学

    爬虫具有域名切换.信息收集以及信息存储功能. 这里讲述如何构建基础的爬虫架构. 1. urllib库:包含从网络请求数据.处理cookie.改变请求头和用户处理元数据的函数.是python标准库.urlopen用于打开读取一个从网络获取的远程对象.能轻松读取HTML文件.图像文件及其他文件流. 2. beautifulsoup库:通过定位HTML标签格式化和组织复杂的网络信息,用python对象展现XML结构信息.不是标准库,可用pip安装.常用的对象是BeautifulSoup对象. 1.基础

  • 开发Node CLI构建微信小程序脚手架的示例

    本文介绍了 Node CLI 构建微信小程序脚手架的示例,分享给大家,具体如下: 目的 由于目前公司的 TOC 产品只要是微信小程序,而且随着业务的扩展, 会有更多的需求,创建更多的小程序,为了让团队避免每次开发前花费大量时间做比如工程化的一些配置,以及保持每个项目的一致性, 所以决定做一个 Node CLI 来创建微信小程序脚手架 节省开发前期的大量时间,新项目可以很快开始业务开发 保证项目统一性,有利于团队间的协作及工程化 提升团队基建意识,从枯燥无味的业务开发中脱离出来,尝试新的东西,即使

  • Scrapy基于scrapy_redis实现分布式爬虫部署的示例

    准备工作 1.安装scrapy_redis包,打开cmd工具,执行命令pip install scrapy_redis 2.准备好一个没有BUG,没有报错的爬虫项目 3.准备好redis主服务器还有跟程序相关的mysql数据库 前提mysql数据库要打开允许远程连接,因为mysql安装后root用户默认只允许本地连接,详情请看此文章 部署过程 1.修改爬虫项目的settings文件 在下载的scrapy_redis包中,有一个scheduler.py文件,里面有一个Scheduler类,是用来调

  • 基于selenium-java封装chrome、firefox、phantomjs实现爬虫

    2017年一直以来在公司负责爬虫项目相关工程,主要业务有预定.库存.在开发中也遇到很多问题,随手记录一下,后续会持续更新. chrome.firefox.phantomjs插件安装和版本说明 基于selenium-java封装chrome.firefox.phantomjs实现爬虫 项目下载地址 maven版本说明 <!-- +++|selenium|+++ --> <dependency> <groupId>org.seleniumhq.selenium</gr

随机推荐