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 相关文章推荐
document.documentElement &amp;&amp; document.documentElement.scrollTop
Dec 01 Javascript
JavaScript 捕获窗口关闭事件
Jul 26 Javascript
javascript中&quot;/&quot;运算符常见错误
Oct 13 Javascript
理解Javascript_14_函数形式参数与arguments
Oct 20 Javascript
JavaScript中split与join函数的进阶使用技巧
May 03 Javascript
酷! 不同风格页面布局幻灯片特效js实现
Feb 19 Javascript
浅析javascript中的Event事件
Dec 09 Javascript
js中url对象化管理分析
Dec 29 Javascript
微信小程序webview实现长按点击识别二维码功能示例
Jan 24 Javascript
JS前端知识点总结之页面加载事件,数组操作,DOM节点操作,循环和分支
Jul 04 Javascript
jQuery 筛选器简单操作示例
Oct 02 jQuery
js利用iframe实现选项卡效果
Aug 09 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
将兴奋、喜悦和坎加斯带到戴安娜:亚马逊公主
2020/03/03 欧美动漫
ThinkPHP之M方法实例详解
2014/06/20 PHP
PHP连接数据库实现注册页面的增删改查操作
2016/03/27 PHP
windows系统php环境安装swoole具体步骤
2021/03/04 PHP
jQuery在iframe中无法弹出对话框的解决方法
2014/01/12 Javascript
Redis基本知识、安装、部署、配置笔记
2015/03/05 Javascript
js控制文本框输入的字符类型方法汇总
2015/06/19 Javascript
jQuery实现的产品自动360度旋转展示特效源码分享
2015/08/21 Javascript
JavaScript生成带有缩进的表格代码
2016/06/15 Javascript
JS简单实现仿百度控制台输出信息效果
2016/09/04 Javascript
jQuery插件Echarts实现的渐变色柱状图
2017/03/23 jQuery
Vue项目实现换肤功能的一种方案分析
2019/08/28 Javascript
如何解决日期函数new Date()浏览器兼容性问题
2019/09/11 Javascript
Vue的生命周期操作示例
2019/09/17 Javascript
微信小程序中的video视频实现 自定义播放按钮、封面图、视频封面上文案
2020/01/02 Javascript
JQuery事件委托(适用于给动态生成的脚本元素添加事件)
2020/02/01 jQuery
Python使用文件锁实现进程间同步功能【基于fcntl模块】
2017/10/16 Python
python如何让类支持比较运算
2018/03/20 Python
对python .txt文件读取及数据处理方法总结
2018/04/23 Python
Python实现多线程的两种方式分析
2018/08/29 Python
Python XML转Json之XML2Dict的使用方法
2019/01/15 Python
Pandas之排序函数sort_values()的实现
2019/07/09 Python
pandas的排序和排名的具体使用
2019/07/31 Python
python实现飞机大战小游戏
2019/11/08 Python
用Python画小女孩放风筝的示例
2019/11/23 Python
Python Selenium模块安装使用教程详解
2020/07/09 Python
python 6种方法实现单例模式
2020/12/15 Python
HTML5 history新特性pushState、replaceState及两者的区别
2015/12/26 HTML / CSS
英语老师推荐信
2014/02/26 职场文书
2014全国两会学习心得体会1000字
2014/03/10 职场文书
团组织推荐意见
2015/06/05 职场文书
2016大学生国家助学贷款承诺书
2016/03/25 职场文书
工作转正自我鉴定范文
2019/06/21 职场文书
2019年幼儿园家长接送责任书
2019/10/29 职场文书
MySQL Shell的介绍以及安装
2021/04/24 MySQL
python_tkinter事件类型详情
2022/03/20 Python