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 相关文章推荐
浏览器页面区域大小的js获取方法
Sep 21 Javascript
可恶的ie8提示缺少id未定义
Mar 20 Javascript
js实现图片旋转的三种方法
Apr 10 Javascript
jQuery.Highcharts.js绘制柱状图饼状图曲线图
Mar 14 Javascript
JS显示表格内指定行html代码的方法
Mar 31 Javascript
javascript实现类似百度分享功能的方法
Jul 27 Javascript
jquery实现的伪分页效果代码
Oct 29 Javascript
JavaScript中的跨浏览器事件操作的基本方法整理
May 20 Javascript
jQuery实现的右下角广告窗体跟随效果示例
Sep 16 Javascript
用瀑布流的方式在网页上插入图片的简单实现方法
Sep 23 Javascript
利用js获取下拉框中所选的值
Dec 01 Javascript
JS插入排序简单理解与实现方法分析
Nov 25 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
颠覆常识!无色透明的咖啡诞生了(中日双语)
2021/03/03 咖啡文化
CodeIgniter视图使用注意事项
2016/01/20 PHP
Aster vs Newbee BO5 第二场2.19
2021/03/10 DOTA
让 JavaScript 轻松支持函数重载 (Part 2 - 实现)
2009/08/04 Javascript
JS getStyle获取最终样式函数代码
2010/04/01 Javascript
javascript:void(0)是什么意思示例介绍
2013/11/17 Javascript
解决js下referer兼容各大浏览器的方法
2014/11/03 Javascript
ANGULARJS中使用JQUERY分页控件
2015/09/16 Javascript
JS+CSS3实现超炫的散列画廊特效
2016/07/16 Javascript
ajax图片上传,图片异步上传,更新实例
2016/12/30 Javascript
解决bootstrap中使用modal加载kindeditor时弹出层文本框不能输入的问题
2017/06/05 Javascript
用JS实现简单的登录验证功能
2017/07/28 Javascript
Vue.js在数组中插入重复数据的实现代码
2017/11/17 Javascript
vue-cli webpack 引入jquery的方法
2018/01/10 jQuery
vue中node_modules中第三方模块的修改使用详解
2019/05/31 Javascript
小程序实现悬浮搜索框
2019/07/12 Javascript
微信小程序(订阅消息)功能
2019/10/25 Javascript
Vue-cli3生成的Vue项目加载Mxgraph方法示例
2020/05/31 Javascript
2分钟实现一个Vue实时直播系统的示例代码
2020/06/05 Javascript
[53:21]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS LGD-CDEC
2014/05/22 DOTA
跟老齐学Python之有容乃大的list(1)
2014/09/14 Python
线程和进程的区别及Python代码实例
2015/02/04 Python
使用Python实现跳帧截取视频帧
2019/05/31 Python
python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
2020/04/08 Python
解决python打开https出现certificate verify failed的问题
2020/09/03 Python
Python基于locals返回作用域字典
2020/10/17 Python
python 实现简单的计算器(gui界面)
2020/11/11 Python
涂鸦板简单实现 Html5编写属于自己的画画板
2016/07/05 HTML / CSS
Bibloo荷兰:女士、男士和儿童的服装、鞋子和配饰
2019/02/25 全球购物
2014年音乐教师工作总结
2014/12/03 职场文书
简历自荐信范文
2015/03/09 职场文书
事业单位财务人员岗位职责
2015/04/14 职场文书
大学生团日活动总结
2015/05/06 职场文书
go原生库的中bytes.Buffer用法
2021/04/25 Golang
Java存储没有重复元素的数组
2022/04/29 Java/Android
uniapp引入支付宝原生扫码插件步骤详解
2022/07/23 Javascript