Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件的方法


Posted in Javascript onSeptember 20, 2017

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

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

Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件的方法

Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件的方法

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

crawler.js:

var http = require('http');
var cheerio = require('cheerio');
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
var DB_URL = 'mongodb://localhost:27017/crawler';

var aList = []; //博客文章列表信息
var aUrl = []; //博客所有的文章url

var db = mongoose.createConnection(DB_URL);
db.on('connected', function (err) {
 if (err) {
  console.log(err);
 } else {
  console.log('db connected success');
 }
});
var Schema = mongoose.Schema;
var arcSchema = new Schema({
 id: Number, //文章id
 title: String, //文章标题
 url: String, //文章链接
 body: String, //文章内容
 entry: String, //摘要
 listTime: Date //发布时间
});
var Article = db.model('Article', arcSchema);

function saveArticle(arcInfo) {
 var arcModel = new Article(arcInfo);
 arcModel.save(function (err, result) {
  if (err) {
   console.log(err);
  } else {
   console.log(`${arcInfo['title']} 插入成功`);
  }
 });
}

function filterArticle(html) {
 var $ = cheerio.load(html);
 var arcDetail = {};
 var title = $("#cb_post_title_url").text();
 var href = $("#cb_post_title_url").attr("href");
 var re = /\/(\d+)\.html/;
 var id = href.match(re)[1];
 var body = $("#cnblogs_post_body").html();
 return {
  id: id,
  title: title,
  url: href,
  body: body
 };
}

function crawlerArc(url) {
 var html = '';
 var str = '';
 var arcDetail = {};
 http.get(url, function (res) {
  res.on('data', function (chunk) {
   html += chunk;
  });
  res.on('end', function () {
   arcDetail = filterArticle(html);
   saveArticle(arcDetail);
   if ( aUrl.length ) {
    setTimeout(function () {
     if (aUrl.length) {
      crawlerArc(aUrl.shift());
     }
    }, 100);
   }else {
    console.log( '采集任务完成' );
    return;
   }
  });
 });
}

function filterHtml(html) {
 var $ = cheerio.load(html);
 var arcList = [];
 var aPost = $("#content").find(".post-list-item");
 aPost.each(function () {
  var ele = $(this);
  var title = ele.find("h2 a").text();
  var url = ele.find("h2 a").attr("href");
  ele.find(".c_b_p_desc a").remove();
  var entry = ele.find(".c_b_p_desc").text();
  ele.find("small a").remove();
  var listTime = ele.find("small").text();
  var re = /\d{4}-\d{2}-\d{2}\s*\d{2}[:]\d{2}/;
  listTime = listTime.match(re)[0];

  arcList.push({
   title: title,
   url: url,
   entry: entry,
   listTime: listTime
  });
 });
 return arcList;
}

function nextPage(html) {
 var $ = cheerio.load(html);
 var nextUrl = $("#pager a:last-child").attr('href');
 if (!nextUrl) return getArcUrl(aList);
 var curPage = $("#pager .current").text();
 if (!curPage) curPage = 1;
 var nextPage = nextUrl.substring(nextUrl.indexOf('=') + 1);
 if (curPage < nextPage) crawler(nextUrl);
}

function crawler(url) {
 http.get(url, function (res) {
  var html = '';
  res.on('data', function (chunk) {
   html += chunk;
  });
  res.on('end', function () {
   aList.push(filterHtml(html));
   nextPage(html);
  });
 });
}

function getArcUrl(arcList) {
 for (var key in arcList) {
  for (var k in arcList[key]) {
   aUrl.push(arcList[key][k]['url']);
  }
 }
 crawlerArc(aUrl.shift());
}

var url = 'http://www.cnblogs.com/ghostwu/';
crawler(url);

其他的核心模块没有怎么改动,主要增加了数据库连接,数据库创建,集合创建( 集合相当于关系型数据库中的表 ),Schema( 相当于关系型数据库的表结构 ).

mongoose操作数据库( save:插入数据 ).分离了文件生成模块.

makeHtml.js文件

var fs = require('fs');
var jade = require('jade');

var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
var DB_URL = 'mongodb://localhost:27017/crawler';

var allArc = [];
var count = 0;

var db = mongoose.createConnection(DB_URL);
db.on('connected', function (err) {
 if (err) {
  console.log(err);
 } else {
  console.log('db connected success');
 }
});
var Schema = mongoose.Schema;
var arcSchema = new Schema({
 id: Number, //文章id
 title: String, //文章标题
 url: String, //文章链接
 body: String, //文章内容
 entry: String, //摘要
 listTime: Date //发布时间
});
var Article = db.model('Article', arcSchema);

function makeHtml(arcDetail) {
 str = jade.renderFile('./views/layout.jade', arcDetail);
 ++count;
 fs.writeFile('./html/' + count + '.html', str, function (err) {
  if (err) {
   console.log(err);
  }
  console.log( `${arcDetail['id']}.html创建成功` + count );
  if ( allArc.length ){
   setTimeout( function(){
    makeHtml( allArc.shift() );
   }, 100 );
  }
 });
}

function getAllArc(){
 Article.find( {}, function( err, arcs ){
  allArc = arcs;
  makeHtml( allArc.shift() );
 } ).sort( { 'id' : 1 } );
}
getAllArc();

以上这篇Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
借用Google的Javascript API Loader来加速你的网站
Jan 28 Javascript
Javascript事件热键兼容ie|firefox
Dec 30 Javascript
jquery隐藏标签和显示标签的实例
Nov 11 Javascript
JS获取几种URL地址的方法小结
Feb 26 Javascript
node.js中的fs.readFileSync方法使用说明
Dec 15 Javascript
简单讲解AngularJS的Routing路由的定义与使用
Mar 05 Javascript
javaScript数组迭代方法详解
Apr 14 Javascript
JavaScript学习总结之正则的元字符和一些简单的应用
Jun 30 Javascript
BootStrap模态框和select2合用时input无法获取焦点的解决方法
Sep 01 Javascript
关于react中组件通信的几种方式详解
Dec 10 Javascript
解决jquery有正确返回值但不执行success函数的问题
Aug 20 jQuery
antd组件Upload实现自己上传的实现示例
Dec 18 Javascript
jquery 一键复制到剪切板的实例
Sep 20 #jQuery
angularjs利用directive实现移动端自定义软键盘的示例
Sep 20 #Javascript
集合Bootstrap自定义confirm提示效果
Sep 19 #Javascript
微信小程序使用Socket的实例
Sep 19 #Javascript
vue基于Element构建自定义树的示例代码
Sep 19 #Javascript
Vue2.0父组件与子组件之间的事件发射与接收实例代码
Sep 19 #Javascript
详解ES6之async+await 同步/异步方案
Sep 19 #Javascript
You might like
《PHP边学边教》(02.Apache+PHP环境配置――上篇)
2006/12/13 PHP
php下载文件的代码示例
2012/06/29 PHP
thinkphp实现数组分页示例
2014/04/13 PHP
PHP callback函数使用方法和注意事项
2015/01/23 PHP
详解PHP安装mysql.so扩展的方法
2016/12/31 PHP
php实现简单的守护进程创建、开启与关闭操作
2019/08/13 PHP
基于jquery的网站幻灯片切换效果焦点图代码
2013/09/15 Javascript
js实现简单的星级选择器提交效果适用于评论等
2013/10/18 Javascript
jQuery实现仿Alipay支付宝首页全屏焦点图切换特效
2015/05/04 Javascript
javascript实现Email邮件显示与删除功能
2015/11/21 Javascript
Javascript实现苹果悬浮虚拟按钮
2016/04/10 Javascript
js中判断变量类型函数typeof的用法总结
2016/08/09 Javascript
JS去除重复并统计数量的实现方法
2016/12/15 Javascript
JS实现动态修改table及合并单元格的方法示例
2017/02/20 Javascript
iOS + node.js使用Socket.IO框架进行实时通信示例
2017/04/14 Javascript
JavaScript中数组常见操作技巧
2017/09/01 Javascript
vue-cli开发时,关于ajax跨域的解决方法(推荐)
2018/02/03 Javascript
jQuery实现模拟搜索引擎的智能提示功能简单示例
2019/01/27 jQuery
nodejs如何在package.json中设置多条启动命令
2020/03/16 NodeJs
Element Badge标记的使用方法
2020/07/27 Javascript
element-ui点击查看大图的方法示例
2020/12/14 Javascript
通过Python来使用七牛云存储的方法详解
2015/08/07 Python
Python递归函数定义与用法示例
2017/06/02 Python
Django中Forms的使用代码解析
2018/02/10 Python
对python3 Serial 串口助手的接收读取数据方法详解
2019/06/12 Python
django 中使用DateTime常用的时间查询方式
2019/12/03 Python
Python面向对象程序设计之类和对象、实例变量、类变量用法分析
2020/03/23 Python
python能做哪些生活有趣的事情
2020/09/09 Python
Madewell美德威尔美国官网:美国休闲服饰品牌
2016/11/25 全球购物
Merrell美国官网:美国登山运动鞋品牌
2018/02/07 全球购物
Shopbop中文官网:美国亚马逊旗下时尚购物网站
2020/12/15 全球购物
迟到检讨书1000字
2014/01/15 职场文书
公司授权委托书范本
2014/04/03 职场文书
经典团队口号
2014/06/06 职场文书
县政府领导班子“四风”方面突出问题整改措施
2014/09/23 职场文书
2016年社区创先争优活动总结
2016/04/05 职场文书