Node.js+jade抓取博客所有文章生成静态html文件的实例


Posted in Javascript onSeptember 19, 2017

这篇文章,我们就把上文中采集到的所有文章列表的信息整理一下,开始采集文章并且生成静态html文件了.先看下我的采集效果,我的博客目前77篇文章,1分钟不到就全部采集生成完毕了,这里我截了部分的图片,文件名用文章的id生成的,生成的文章,我写了一个简单的静态模板,所有的文章都是根据这个模板生成的.

项目结构:

Node.js+jade抓取博客所有文章生成静态html文件的实例

Node.js+jade抓取博客所有文章生成静态html文件的实例

Node.js+jade抓取博客所有文章生成静态html文件的实例

好了,接下来,我们就来讲解下,这篇文章主要实现的功能:

1,抓取文章,主要抓取文章的标题,内容,超链接,文章id(用于生成静态html文件)

2,根据jade模板生成html文件

一、抓取文章如何实现?

非常简单,跟上文抓取文章列表的实现差不多

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 );
      str = jade.renderFile('./views/layout.jade', arcDetail );
      fs.writeFile( './html/' + arcDetail['id'] + '.html', str, function( err ){
        if( err ) {
          console.log( err );
        }
        console.log( 'success:' + url );
        if ( aUrl.length ) crawlerArc( aUrl.shift() );
      } );
    });
  });
}

参数url就是文章的地址,把文章的内容抓取完毕之后,调用filterArticle( html ) 过滤出需要的文章信息(id, 标题,超链接,内容),然后用jade的renderFile这个api,实现模板内容的替换,

模板内容替换完之后,肯定就需要生成html文件了, 所以用writeFile写入文件,写入文件时候,用id作为html文件名称。这就是生成一篇静态html文件的实现,

接下来就是循环生成静态html文件了, 就是下面这行:

if ( aUrl.length ) crawlerArc( aUrl.shift() );

aUrl保存的是我的博客所有文章的url, 每次采集完一篇文章之后,就把当前文章的url删除,让下一篇文章的url出来,继续采集

完整的实现代码server.js:

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

var aList = [];
var aUrl = [];

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,
    href : 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 );
      str = jade.renderFile('./views/layout.jade', arcDetail );
      fs.writeFile( './html/' + arcDetail['id'] + '.html', str, function( err ){
        if( err ) {
          console.log( err );
        }
        console.log( 'success:' + url );
        if ( aUrl.length ) crawlerArc( aUrl.shift() );
      } );
    });
  });
}

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 );

layout.jade文件:

doctype html
html
  head
    meta(charset='utf-8')
    title jade+node.js express
    link(rel="stylesheet", href='./css/bower_components/bootstrap/dist/css/bootstrap.min.css')
  body
    block header
      div.container
        div.well.well-lg
          h3 ghostwu的博客
          p js高手之路
    block container
      div.container
        h3
          a(href="#{href}" rel="external nofollow" ) !{title}
        p !{body}
    block footer
      div.container
        footer 版权所有 - by ghostwu

后续的打算:

1,采用mongodb入库

2,支持断点采集

3,采集图片

4,采集小说

等等....

以上这篇Node.js+jade抓取博客所有文章生成静态html文件的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Opacity.js
Jan 22 Javascript
js验证上传图片的方法
May 12 Javascript
浅谈JavaScript字符串与数组
Jun 03 Javascript
jquery插件autocomplete用法示例
Jul 01 Javascript
使用jquery.qrcode.js生成二维码插件
Oct 17 Javascript
浅析JavaScript的几种Math函数,random(),ceil(),round(),floor()
Dec 22 Javascript
bootstrap3中container与container_fluid外层容器的区别讲解
Dec 04 Javascript
Vue组件开发技巧总结
Mar 04 Javascript
深入理解JavaScript 中的匿名函数((function() {})();)与变量的作用域
Aug 28 Javascript
Vue2.0 v-for filter列表过滤功能的实现
Sep 07 Javascript
jquery实现图片无缝滚动 蒙版遮蔽效果
Jan 11 jQuery
快速解决element的autofocus失效问题
Sep 08 Javascript
Node.js中Bootstrap-table的两种分页的实现方法
Sep 18 #Javascript
Node.js 使用递归实现遍历文件夹中所有文件
Sep 18 #Javascript
Node.JS 循环递归复制文件夹目录及其子文件夹下的所有文件
Sep 18 #Javascript
为什么我们要做三份 Webpack 配置文件
Sep 18 #Javascript
分析javascript中9 个常见错误阻碍你进步
Sep 18 #Javascript
十个免费的web前端开发工具详细整理
Sep 18 #Javascript
Redux 和 Mobx的选择问题:让你不再困惑!
Sep 18 #Javascript
You might like
php5.3 废弃函数小结
2010/05/16 PHP
上传文件先创建目录 再上传到目录里面去
2010/12/29 PHP
教你php如何实现验证码
2016/01/20 PHP
thinkPHP3.x常量整理(预定义常量/路径常量/系统常量)
2016/05/20 PHP
ThinkPHP和UCenter接口冲突的解决方法
2016/07/25 PHP
使用js操作cookie的一点小收获分享
2013/09/03 Javascript
jquery $.fn $.fx是什么意思有什么用
2013/11/04 Javascript
Bootstrap导航栏各元素操作方法(表单、按钮、文本)
2015/12/28 Javascript
easyui window refresh 刷新两次的解决方法(推荐)
2016/05/18 Javascript
JavaScript操作表单实例讲解(上)
2016/06/20 Javascript
使用snowfall.jquery.js实现爱心满屏飞的效果
2017/01/05 Javascript
教你用十行node.js代码读取docx的文本
2017/03/08 Javascript
深入理解JavaScript创建对象的多种方式以及优缺点
2017/06/01 Javascript
JS 60秒后重新发送验证码的实例讲解
2017/07/26 Javascript
React Hooks的深入理解与使用
2018/11/12 Javascript
微信小程序自定义导航教程(兼容各种手机)
2018/12/12 Javascript
vue项目创建并引入饿了么elementUI组件的步骤
2019/04/11 Javascript
JavaScript碰撞检测原理及其实现代码
2020/03/12 Javascript
使用Python的Twisted框架实现一个简单的服务器
2015/04/16 Python
轻松掌握python设计模式之访问者模式
2016/11/18 Python
Python set常用操作函数集锦
2017/11/15 Python
tensorflow 变长序列存储实例
2020/01/20 Python
Tensorflow中的降维函数tf.reduce_*使用总结
2020/04/20 Python
python三引号如何输入
2020/07/06 Python
用Python自动清理电脑内重复文件,只要10行代码(自动脚本)
2021/01/09 Python
Conforama瑞士:家具、厨房、电器、装饰
2020/09/06 全球购物
什么是lambda函数
2013/09/17 面试题
二年级语文教学反思
2014/02/02 职场文书
酒店营销策划方案
2014/02/07 职场文书
挖掘机司机岗位职责
2014/02/12 职场文书
2014全国两会学习心得体会2000字
2014/03/10 职场文书
《三个小伙伴》教学反思
2014/04/11 职场文书
勤奋学习演讲稿
2014/05/10 职场文书
报到证办理个人委托书
2014/10/06 职场文书
六一亲子活动感想
2015/08/07 职场文书
解决pycharm下载库时出现Failed to install package的问题
2021/09/04 Python