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拥有类似Lambda表达式编程能力的方法
Sep 12 Javascript
javascript笔记 String类replace函数的一些事
Sep 22 Javascript
js查找节点的方法小结
Jan 13 Javascript
headjs实现网站并行加载但顺序执行JS
Nov 29 Javascript
vue通过watch对input做字数限定的方法
Jul 13 Javascript
Javascript中从学习bind到实现bind的过程
Jan 05 Javascript
Vue项目中添加锁屏功能实现思路
Jun 29 Javascript
解决layer弹层遮罩挡住窗体的问题
Aug 17 Javascript
vue实现一个炫酷的日历组件
Oct 08 Javascript
深入浅析js原型链和vue构造函数
Oct 25 Javascript
微信小程序下拉加载和上拉刷新两种实现方法详解
Sep 05 Javascript
详解JavaScript 异步编程
Jul 13 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
PHP 文章中的远程图片采集到本地的代码
2009/07/30 PHP
Laravel框架实现抢红包功能示例
2019/10/31 PHP
列表内容的选择
2006/06/30 Javascript
分析 JavaScript 中令人困惑的变量赋值
2007/08/13 Javascript
jQuery 图像裁剪插件Jcrop的简单使用
2009/05/22 Javascript
JQuery一种取同级值的方式(比如你在GridView中)
2012/03/15 Javascript
jQuery操作CheckBox的方法介绍(选中,取消,取值)
2014/02/04 Javascript
javascript 小数取整简单实现方式
2014/05/30 Javascript
Egret引擎开发指南之发布项目
2014/09/03 Javascript
鼠标悬浮显示二级菜单效果的jquery实现
2014/10/29 Javascript
Javascript设计模式理论与编程实战之简单工厂模式
2015/11/03 Javascript
深入理解JavaScript中为什么string可以拥有方法
2016/05/24 Javascript
jQuery Easyui DataGrid点击某个单元格即进入编辑状态焦点移开后保存数据
2016/08/15 Javascript
用angular实现多选按钮的全选与反选实例代码
2017/05/23 Javascript
一秒学会微信小程序制作table表格
2019/02/14 Javascript
[10:07]2014DOTA2国际邀请赛 实拍选手现场观战DK对阵Titan
2014/07/12 DOTA
深入解析Python中的WSGI接口
2015/05/11 Python
Python matplotlib绘图可视化知识点整理(小结)
2018/03/16 Python
Pyqt5如何让QMessageBox按钮显示中文示例代码
2019/04/11 Python
python实现图像检索的三种(直方图/OpenCV/哈希法)
2019/08/08 Python
tensorflow 保存模型和取出中间权重例子
2020/01/24 Python
python实现根据给定坐标点生成多边形mask的例子
2020/02/18 Python
python rolling regression. 使用 Python 实现滚动回归操作
2020/06/08 Python
python如何快速生成时间戳
2020/07/21 Python
美国零售商店:Blue&Cream
2017/04/07 全球购物
YSL圣罗兰美妆官方旗舰店:购买YSL口红
2018/04/16 全球购物
施华洛世奇日本官网:SWAROVSKI日本
2018/05/04 全球购物
程序员经常用到的UNIX命令
2015/04/13 面试题
乡镇信息公开实施方案
2014/03/23 职场文书
企业总经理助理岗位职责
2014/09/12 职场文书
个人授权委托书模板
2014/09/14 职场文书
党员学习群众路线心得体会
2014/11/04 职场文书
2015年大学生党员承诺书
2015/04/27 职场文书
创业开店,这样方式更合理
2019/08/26 职场文书
vue+elementui 实现新增和修改共用一个弹框的完整代码
2021/06/08 Vue.js
基于Python编写简易版的天天跑酷游戏的示例代码
2022/03/23 Python