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 相关文章推荐
Js 本页面传值实现代码
May 17 Javascript
Jquery图形报表插件 jqplot简介及参数详解
Oct 10 Javascript
jQuery制作的别致导航有阴影背景高亮模式窗口
Apr 15 Javascript
jQuery中关于ScrollableGridPlugin.js(固定表头)插件的使用逐步解析
Jul 17 Javascript
jquery操作复选框checkbox的方法汇总
Feb 05 Javascript
jQuery统计指定子元素数量的方法
Mar 17 Javascript
AngularJS基础知识笔记之表格
May 10 Javascript
利用JS生成博文目录及CSS定制博客
Feb 10 Javascript
获取阴历(农历)和当前日期的js代码
Feb 15 Javascript
微信小程序之发送短信倒计时功能
Aug 30 Javascript
jquery实现聊天机器人
Feb 08 jQuery
vue+iview实现分页及查询功能
Nov 17 Vue.js
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+mysql 采用ajax技术的 省 市 地 3级联动无刷新菜单 源码
2006/12/16 PHP
apache2.2.4+mysql5.0.77+php5.2.8安装精简
2009/04/29 PHP
thinkPHP5.0框架独立配置与动态配置方法
2017/03/17 PHP
js类中的公有变量和私有变量
2008/07/24 Javascript
img onload事件绑定各浏览器均可执行
2012/12/19 Javascript
JavaScript中的DSL元编程介绍
2015/03/15 Javascript
如何检测JavaScript的各种类型
2016/07/30 Javascript
模板视图和AngularJS之间冲突的解决方法
2016/11/22 Javascript
详解vue.js全局组件和局部组件
2017/04/10 Javascript
vue-axios使用详解
2017/05/10 Javascript
JS实现的杨辉三角【帕斯卡三角形】算法示例
2019/02/26 Javascript
一篇文章介绍redux、react-redux、redux-saga总结
2019/05/23 Javascript
CountUp.js实现数字滚动增值效果
2019/10/17 Javascript
node.js使用yargs处理命令行参数操作示例
2020/02/11 Javascript
vue实现循环滚动列表
2020/06/30 Javascript
[59:08]Ti4 冒泡赛第二天 NEWBEE vs Titan 2
2014/07/15 DOTA
python定时采集摄像头图像上传ftp服务器功能实现
2013/12/23 Python
python使用新浪微博api上传图片到微博示例
2014/01/10 Python
python检查指定文件是否存在的方法
2015/07/06 Python
Python实现将数据写入netCDF4中的方法示例
2018/08/30 Python
python 实现弹球游戏的示例代码
2020/11/17 Python
Python爬虫进阶之爬取某视频并下载的实现
2020/12/08 Python
HTML5 video 视频标签使用介绍
2014/02/03 HTML / CSS
html5小程序飞入购物车(抛物线绘制运动轨迹点)
2020/10/19 HTML / CSS
违反校纪校规检讨书
2014/02/15 职场文书
党委领导班子整改方案
2014/09/30 职场文书
党员对照检查剖析材料
2014/10/13 职场文书
2015年城市管理工作总结
2015/05/23 职场文书
小学教育见习总结
2015/06/23 职场文书
中学团支部工作总结
2015/08/13 职场文书
七年级生物教学反思
2016/02/20 职场文书
资产移交协议书
2016/03/24 职场文书
如何使用flask将模型部署为服务
2021/05/13 Python
php+laravel 扫码二维码签到功能
2021/05/15 PHP
python使用PySimpleGUI设置进度条及控件使用
2021/06/10 Python
Win11安装升级时提示“该电脑必须支持安全启动”
2022/04/19 数码科技