[js高手之路]Node.js jade mongodb mongoose实现爬虫分离入库与生成静态文件

本文主要是介绍[js高手之路]Node.js jade mongodb mongoose实现爬虫分离入库与生成静态文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

接着这篇文章[js高手之路]Node.js jade抓取博客所有文章生成静态html文件继续,在这篇文章中实现了采集与静态文件的生成,在实际的采集项目中, 应该是先入库再选择性的生成静态文件。

那么我选择的数据库是mongodb,为什么用这个数据库,因为这个数据库是基于集合,数据的操作基本是json,与dom模块cheerio具有非常大的亲和力,cheerio处理过滤出来的数据,可以直接插入mongodb,不需要经过任何的处理,非常的便捷,当然跟node.js的亲和力那就不用说了,更重要的是,性能很棒。这篇文章我就不具体写mongodb的基本用法,到时候会另起文章从0开始写mongodb基本常用用法.先看下入库的效果与生成静态文件的效果:

我在这个阶段,把爬虫分离成2个模块,采集入库( crawler.js ), 生成静态文件(makeHtml.js).

crawler.js:

  1 var http = require('http');
  2 var cheerio = require('cheerio');
  3 var mongoose = require('mongoose');
  4 mongoose.Promise = global.Promise;
  5 var DB_URL = 'mongodb://localhost:27017/crawler';
  6 
  7 var aList = []; //博客文章列表信息
  8 var aUrl = []; //博客所有的文章url
  9 
 10 var db = mongoose.createConnection(DB_URL);
 11 db.on('connected', function (err) {
 12     if (err) {
 13         console.log(err);
 14     } else {
 15         console.log('db connected success');
 16     }
 17 });
 18 var Schema = mongoose.Schema;
 19 var arcSchema = new Schema({
 20     id: Number, //文章id
 21     title: String, //文章标题
 22     url: String, //文章链接
 23     body: String, //文章内容
 24     entry: String, //摘要
 25     listTime: Date //发布时间
 26 });
 27 var Article = db.model('Article', arcSchema);
 28 
 29 function saveArticle(arcInfo) {
 30     var arcModel = new Article(arcInfo);
 31     arcModel.save(function (err, result) {
 32         if (err) {
 33             console.log(err);
 34         } else {
 35             console.log(`${arcInfo['title']}   插入成功`);
 36         }
 37     });
 38 }
 39 
 40 function filterArticle(html) {
 41     var $ = cheerio.load(html);
 42     var arcDetail = {};
 43     var title = $("#cb_post_title_url").text();
 44     var href = $("#cb_post_title_url").attr("href");
 45     var re = /\/(\d )\.html/;
 46     var id = href.match(re)[1];
 47     var body = $("#cnblogs_post_body").html();
 48     return {
 49         id: id,
 50         title: title,
 51         url: href,
 52         body: body
 53     };
 54 }
 55 
 56 function crawlerArc(url) {
 57     var html = '';
 58     var str = '';
 59     var arcDetail = {};
 60     http.get(url, function (res) {
 61         res.on('data', function (chunk) {
 62             html  = chunk;
 63         });
 64         res.on('end', function () {
 65             arcDetail = filterArticle(html);
 66             saveArticle(arcDetail);
 67             if ( aUrl.length ) {
 68                 setTimeout(function () {
 69                     if (aUrl.length) {
 70                         crawlerArc(aUrl.shift());
 71                     }
 72                 }, 100);
 73             }else {
 74                 console.log( '采集任务完成' );
 75                 return;
 76             }
 77         });
 78     });
 79 }
 80 
 81 function filterHtml(html) {
 82     var $ = cheerio.load(html);
 83     var arcList = [];
 84     var aPost = $("#content").find(".post-list-item");
 85     aPost.each(function () {
 86         var ele = $(this);
 87         var title = ele.find("h2 a").text();
 88         var url = ele.find("h2 a").attr("href");
 89         ele.find(".c_b_p_desc a").remove();
 90         var entry = ele.find(".c_b_p_desc").text();
 91         ele.find("small a").remove();
 92         var listTime = ele.find("small").text();
 93         var re = /\d{4}-\d{2}-\d{2}\s*\d{2}[:]\d{2}/;
 94         listTime = listTime.match(re)[0];
 95 
 96         arcList.push({
 97             title: title,
 98             url: url,
 99             entry: entry,
100             listTime: listTime
101         });
102     });
103     return arcList;
104 }
105 
106 function nextPage(html) {
107     var $ = cheerio.load(html);
108     var nextUrl = $("#pager a:last-child").attr('href');
109     if (!nextUrl) return getArcUrl(aList);
110     var curPage = $("#pager .current").text();
111     if (!curPage) curPage = 1;
112     var nextPage = nextUrl.substring(nextUrl.indexOf('=')   1);
113     if (curPage < nextPage) crawler(nextUrl);
114 }
115 
116 function crawler(url) {
117     http.get(url, function (res) {
118         var html = '';
119         res.on('data', function (chunk) {
120             html  = chunk;
121         });
122         res.on('end', function () {
123             aList.push(filterHtml(html));
124             nextPage(html);
125         });
126     });
127 }
128 
129 function getArcUrl(arcList) {
130     for (var key in arcList) {
131         for (var k in arcList[key]) {
132             aUrl.push(arcList[key][k]['url']);
133         }
134     }
135     crawlerArc(aUrl.shift());
136 }
137 
138 var url = 'http://www.cnblogs.com/ghostwu/';
139 crawler(url);

其他的核心模块没有怎么改动,主要增加了数据库连接,数据库创建,集合创建( 集合相当于关系型数据库中的表 ),Schema( 相当于关系型数据库的表结构 ).
mongoose操作数据库( save:插入数据 ).分离了文件生成模块.

makeHtml.js文件
 1 var fs = require('fs');
 2 var jade = require('jade');
 3 
 4 var mongoose = require('mongoose');
 5 mongoose.Promise = global.Promise;
 6 var DB_URL = 'mongodb://localhost:27017/crawler';
 7 
 8 var allArc = [];
 9 var count = 0;
10 
11 var db = mongoose.createConnection(DB_URL);
12 db.on('connected', function (err) {
13     if (err) {
14         console.log(err);
15     } else {
16         console.log('db connected success');
17     }
18 });
19 var Schema = mongoose.Schema;
20 var arcSchema = new Schema({
21     id: Number, //文章id
22     title: String, //文章标题
23     url: String, //文章链接
24     body: String, //文章内容
25     entry: String, //摘要
26     listTime: Date //发布时间
27 });
28 var Article = db.model('Article', arcSchema);
29 
30 function makeHtml(arcDetail) {
31     str = jade.renderFile('./views/layout.jade', arcDetail);
32       count;
33     fs.writeFile('./html/'   count   '.html', str, function (err) {
34         if (err) {
35             console.log(err);
36         }
37         console.log( `${arcDetail['id']}.html创建成功`   count );
38         if ( allArc.length ){
39             setTimeout( function(){
40                 makeHtml( allArc.shift() );
41             }, 100 );
42         }
43     });
44 }
45 
46 function getAllArc(){
47     Article.find( {}, function( err, arcs ){
48         allArc = arcs;
49         makeHtml( allArc.shift() );
50     } ).sort( { 'id' : 1 } );
51 }
52 getAllArc();

 

这篇关于[js高手之路]Node.js jade mongodb mongoose实现爬虫分离入库与生成静态文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1076911

相关文章

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手!🌟 什么是Kimi? 一款月之暗面科技有限公司开发的AI办公工具,帮助用户快速生成高质量的演示文稿。 无论你是职场人士、学生还是教师,Kimi都能够为你的办公文

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma