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 相关文章推荐
jQuery探测位置的提示弹窗(toolTip box)详细解析
Nov 14 Javascript
Angularjs中如何使用filterFilter函数过滤
Feb 06 Javascript
JavaScript图像延迟加载库Echo.js
Apr 05 Javascript
Web Uploader文件上传插件使用详解
May 10 Javascript
分享10个优化代码的CSS和JavaScript工具
May 11 Javascript
Bootstrap Table从服务器加载数据进行显示的实现方法
Sep 29 Javascript
javascript设置文本框光标的方法实例小结
Nov 04 Javascript
微信小程序 Template详解及简单实例
Jan 05 Javascript
vue增删改查的简单操作
Jul 15 Javascript
使用vuepress搭建静态博客的示例代码
Feb 14 Javascript
一文了解Vue中的nextTick
May 06 Javascript
vue-cli3跨域配置的简单方法
Sep 06 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
让你同时上传 1000 个文件 (一)
2006/10/09 PHP
php模拟post行为代码总结(POST方式不是绝对安全)
2012/02/22 PHP
yii2实现 &quot;上一篇,下一篇&quot; 功能的代码实例
2017/02/04 PHP
phpMyAdmin通过密码漏洞留后门文件
2018/11/20 PHP
来自chinaz的ajax获取评论代码
2008/05/03 Javascript
juqery 学习之三 选择器 可见性 元素属性
2010/11/25 Javascript
jquery中的事件处理详细介绍
2013/06/24 Javascript
使用jQuery jqPlot插件绘制柱状图
2014/12/18 Javascript
jQuery DOM插入节点操作指南
2015/03/03 Javascript
JS正则表达式之非捕获分组用法实例分析
2016/12/28 Javascript
bootstrap treeview 扩展addNode方法动态添加子节点的方法
2017/11/21 Javascript
vue页面切换到滚动页面显示顶部的实例
2018/03/13 Javascript
Vue使用mixins实现压缩图片代码
2018/03/14 Javascript
nodejs使用async模块同步执行的方法
2019/03/02 NodeJs
vue+koa2实现session、token登陆状态验证的示例
2019/08/30 Javascript
layui点击按钮页面会自动刷新的解决方案
2019/10/25 Javascript
node.js中fs文件系统模块的使用方法实例详解
2020/02/13 Javascript
基于Web Audio API实现音频可视化效果
2020/06/12 Javascript
详解Webpack4多页应用打包方案
2020/07/16 Javascript
python获取糗百图片代码实例
2013/12/18 Python
星球大战与Python之间的那些事
2016/01/07 Python
python编码总结(编码类型、格式、转码)
2016/07/01 Python
简单谈谈python中的多进程
2016/11/06 Python
解决python删除文件的权限错误问题
2018/04/24 Python
对python程序内存泄漏调试的记录
2018/06/11 Python
Python3爬楼梯算法示例
2019/03/04 Python
Python如何实现动态数组
2019/11/02 Python
美国维生素、补充剂、保健食品购物网站:Vitacost
2016/08/05 全球购物
英国玛莎百货澳大利亚:Marks & Spencer Australia
2019/08/30 全球购物
Contém1g官网:巴西彩妆品牌
2020/01/17 全球购物
大学生自我鉴定
2013/12/16 职场文书
作风年建设汇报材料
2014/08/14 职场文书
2015年党员自我剖析材料
2014/12/17 职场文书
销售工作决心书
2015/02/04 职场文书
CSS预处理框架——Stylus
2021/04/21 HTML / CSS
linux中nohup和后台运行进程查看及终止
2021/06/24 Python