您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    NodeJs爬虫抓取现代典籍,合计16000个页面心得体会总结及项目分享
    时间:2017-12-25 12:40 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    【限时收费】年底最强一次云计算大会,看传统、社区、互联网企业如何碰撞?

    前言

    之前研讨数据,零零散散的写过一些数据抓取的爬虫,不过写的比较随意。有很多中央如今看起来并不是很合理 这段时间比较闲,本来是想给之前的项目做重构的。

    后来 应用这个周末,索性重新写了一个项目,就是本项目 guwen-spider。目前这个爬虫还是比较复杂的类型的, 直接抓取页面,然后在页面中提取数据,保存数据到数据库。

    经过与之前写的比照,我觉得难点在于整个顺序的强健性,以及相应的容错机制。在昨天写代码的进程中其实也有反映, 真正的主体代码其实很快就写完了 ,花了大部分时间是在

    做波动性的调试, 以及寻求一种更合理的方式来处置数据与流程控制的关系。

    NodeJs爬虫抓取现代典籍,合计16000个页面心得体会总结及项目分享

    背景

    项目的背景是抓取一个一级页面是目录列表 ,点击一个目录出来 是一个章节 及篇幅列表 ,点击章节或篇幅进入详细的内容页面。

    概述

    本项目github地址 : guwen-spider (PS:最前面还有彩蛋 ~~逃

    项目技术细节

    项目少量用到了 ES7 的async 函数, 更直观的反响顺序了的流程。为了方便,在对数据遍历的进程中直接运用了著名的async这个库,所以不可避免的还是用到了回调promise ,由于数据的处置发作在回调函数中,不可避免的会遇到一些数据传递的成绩,其实也可以直接用ES7的async await 写一个办法来完成相反的功用。这里其实最赞的一个中央是运用了 Class 的 static 办法封装对数据库的操作, static 望文生义 静态办法 就跟 prototype 一样 ,不会占用额外空间。

    项目主要用到了

    ES7的 async await 协程做异步有关的逻辑处置。

    运用 npm的 async库 来做循环遍历,以及并发央求操作。

    运用 log4js 来做日志处置

    运用 cheerio 来处置dom的操作。

    运用 mongoose 来衔接mongoDB 做数据的保存以及操作。

    目录结构

    ├── bin // 入口

    │ ├── booklist.js // 抓取书籍逻辑

    │ ├── chapterlist.js // 抓取章节逻辑

    │ ├── content.js // 抓取内容逻辑

    │ └── index.js // 顺序入口

    ├── config // 配置文件

    ├── dbhelper // 数据库操作办法目录

    ├── logs // 项目日志目录

    ├── model // mongoDB 集合操作实例

    ├── node_modules

    ├── utils // 工具函数

    ├── package.json

    项目完成方案剖析

    项目是一个典型的多级抓取案例,目前只要三级,即 书籍列表, 书籍项对应的 章节列表,一个章节链接对应的内容。 抓取这样的结构可以采用两种方式, 一是 直接从外层到内层 内层抓取完以后再执行下一个外层的抓取, 还有一种就是先把外层抓取完成保存到数据库,然后依据外层抓取到一切内层章节的链接,再次保存,然后从数据库查询到对应的链接单元 对之停止内容抓取。这两种方案各有利害,其实两种方式我都试过, 后者有一个益处,由于对三个层级是分开抓取的, 这样就可以更方便,尽能够多的保存到对应章节的相关数据。 可以试想一下 ,假设采用前者 按照正常的逻辑

    对一级目录停止遍历抓取到对应的二级章节目录, 再对章节列表停止遍历 抓取内容,到第三级 内容单元抓取完成 需求保存时,假设需求很多的一级目录信息,就需求 这些分层的数据之间停止数据传递 ,想想其实应该是比较复杂的一件事情。所以分开保存数据 一定水平上避开了不必要的复杂的数据传递。

    目前我们思索到 其实我们要抓取到的古文书籍数量并不多,古文书籍大约只要180本囊括了各种经史。其和章节内容本身是一个很小的数据 ,即一个集合外面有180个文档记载。 这180本书一切章节抓取上去一共有一万六千个章节,对应需求拜访一万六千个页面爬取到对应的内容。所以选择第二种应该是合理的。

    项目完成

    主程有三个办法 bookListInit ,chapterListInit,contentListInit, 辨别是抓取书籍目录,章节列表,书籍内容的办法对外地下暴露的初始化办法。经过async 可以完成对这三个办法的运转流程停止控制,书籍目录抓取完成将数据保存到数据库,然后执行结果前往到主顺序,假设运转成功 主顺序则执行依据书籍列表对章节列表的抓取,同理对书籍内容停止抓取。

    项目主入口

    /** 

     * 爬虫抓取主入口 

     */ 

    const start = async() => { 

        let booklistRes = await bookListInit(); 

        if (!booklistRes) { 

            logger.warn('书籍列表抓取出错,顺序终止...'); 

            return

        } 

        logger.info('书籍列表抓取成功,如今停止书籍章节抓取...'); 

     

        let chapterlistRes = await chapterListInit(); 

        if (!chapterlistRes) { 

            logger.warn('书籍章节列表抓取出错,顺序终止...'); 

            return

        } 

        logger.info('书籍章节列表抓取成功,如今停止书籍内容抓取...'); 

     

        let contentListRes = await contentListInit(); 

        if (!contentListRes) { 

            logger.warn('书籍章节内容抓取出错,顺序终止...'); 

            return

        } 

        logger.info('书籍内容抓取成功'); 

    // 末尾入口 

    (责任编辑:admin)