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 相关文章推荐
Javascript 作用域使用说明
Aug 13 Javascript
Jquery cookie操作代码
Mar 14 Javascript
基于KMP算法JavaScript的实现方法分析
May 03 Javascript
jQuery获得指定元素坐标的方法
Apr 14 Javascript
JavaScript数组方法总结分析
May 06 Javascript
一道面试题引发的对javascript类型转换的思考
Mar 06 Javascript
jquery仿微信聊天界面
May 06 jQuery
react-router实现按需加载
May 09 Javascript
AngularJS解决ng-if中的ng-model值无效的问题
Jun 21 Javascript
vue将时间戳转换成自定义时间格式的方法
Mar 02 Javascript
NestJs 静态目录配置详解
Mar 12 Javascript
JavaScript实现字符串与HTML格式相互转换
Mar 17 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
利用js调用后台php进行数据处理原码
2006/10/09 PHP
php几个预定义变量$_SERVER用法小结
2014/11/07 PHP
php去除二维数组的重复项方法
2015/11/03 PHP
3种php生成唯一id的方法
2015/11/23 PHP
FireFox与IE 下js兼容触发click事件的代码
2008/11/20 Javascript
jquery 获取json数据实现代码
2009/04/27 Javascript
比较全面的event对像在IE与FF中的区别 推荐
2009/09/21 Javascript
Javascript学习笔记6 prototype的提出
2010/01/11 Javascript
通过url查找a元素应用案例
2014/04/29 Javascript
深入浅析Vue组件开发
2016/11/25 Javascript
Javascript同时声明一连串(多个)变量的方法
2017/01/23 Javascript
Vue中添加过渡效果的方法
2017/03/16 Javascript
ES6新特性之变量和字符串用法示例
2017/04/01 Javascript
浅谈JS中的反柯里化( uncurrying)
2017/08/17 Javascript
jQuery实现根据身份证号获取生日、年龄、性别等信息的方法
2019/01/09 jQuery
超详细动手搭建一个VuePress 站点及开启PWA与自动部署的方法
2019/01/27 Javascript
js实现图片局部放大效果详解
2019/03/18 Javascript
微信小程序常用的3种提示弹窗实现详解
2019/09/19 Javascript
JS检测浏览器开发者工具是否打开的方法详解
2020/10/02 Javascript
Python去除字符串两端空格的方法
2015/05/21 Python
python3 webp转gif格式的实现示例
2019/12/10 Python
Python获取excel内容及相关操作代码实例
2020/08/10 Python
香港万宁官方海外旗舰店:香港健与美连锁店
2018/09/27 全球购物
英国床垫和床架购物网站:Bedman
2019/11/04 全球购物
光电信息专业应届生求职信
2013/10/07 职场文书
学生评语大全
2014/04/18 职场文书
小学生安全教育广播稿
2014/10/20 职场文书
解除同居协议书
2015/01/29 职场文书
2015年招生工作总结
2015/05/04 职场文书
婚育证明样本
2015/06/16 职场文书
餐厅服务员管理制度
2015/08/05 职场文书
MySQL数据库压缩版本安装与配置详细教程
2021/05/21 MySQL
Python实现简单的猜单词
2021/06/15 Python
美元符号 $
2022/02/17 杂记
排查并解决Oracle sysaux表空间异常增长
2022/04/20 Oracle
Mybatis-Plus 使用 @TableField 自动填充日期
2022/04/26 Java/Android