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判断元素是否隐藏的多种方法
May 06 Javascript
JS实现的竖向折叠菜单代码
Oct 21 Javascript
Angular 路由route实例代码
Jul 12 Javascript
jQuery获取与设置iframe高度的方法
Aug 01 Javascript
jQuery实现的浮动层div浏览器居中显示效果
Feb 03 Javascript
jQuery+PHP+Mysql实现抽奖程序
Apr 12 jQuery
给Easyui-Datebox设置隐藏或者不可用的解决方法
May 26 Javascript
浅析Vue实例以及生命周期
Aug 14 Javascript
Angular 利用路由跳转到指定页面的指定位置方法
Aug 31 Javascript
vue element table 表格请求后台排序的方法
Sep 28 Javascript
如何基于jQuery实现五角星评分
Sep 02 jQuery
javascript的var与let,const之间的区别详解
Feb 18 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支持多种格式图片上传(支持jpg、png、gif)
2011/11/03 PHP
实例讲解PHP设计模式编程中的简单工厂模式
2016/02/29 PHP
PHP新特性详解之命名空间、性状与生成器
2017/07/18 PHP
IE中直接运行显示当前网页中的图片 推荐
2006/08/31 Javascript
location.href 在IE6中不跳转的解决方法与推荐使用代码
2010/07/08 Javascript
jQuery ajax在GBK编码下表单提交终极解决方案(非二次编码方法)
2010/10/20 Javascript
js获取class的所有元素
2013/03/28 Javascript
jQuery基本过滤选择器使用介绍
2013/04/18 Javascript
简介AngularJS中$http服务的用法
2016/02/06 Javascript
JS简单实现数组去重的方法示例
2017/03/27 Javascript
AngularJS实现自定义指令及指令配置项的方法
2017/11/20 Javascript
ajax前台后台跨域请求处理方式
2018/02/08 Javascript
浅谈Vue初学之props的驼峰命名
2018/07/19 Javascript
vue select选择框数据变化监听方法
2018/08/24 Javascript
vue自定义标签和单页面多路由的实现代码
2020/05/03 Javascript
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
2020/08/10 Javascript
vue在App.vue文件中监听路由变化刷新页面操作
2020/08/14 Javascript
微信小程序中data-key属性之数据传输(经验总结)
2020/08/22 Javascript
vue中利用three.js实现全景图的完整示例
2020/12/07 Vue.js
[01:19]DOTA2城市挑战赛报名开始 开启你的城市传奇
2018/03/23 DOTA
教你用python3根据关键词爬取百度百科的内容
2016/08/18 Python
情人节快乐! python绘制漂亮玫瑰
2020/08/18 Python
django 快速启动数据库客户端程序的方法示例
2019/08/16 Python
Python Socketserver实现FTP文件上传下载代码实例
2020/03/27 Python
超全Python图像处理讲解(多模块实现)
2020/04/13 Python
Python基于QQ邮箱实现SSL发送
2020/04/26 Python
Python定义一个Actor任务
2020/07/29 Python
CSS3的resize属性使用初探
2015/09/27 HTML / CSS
html5+css3实现一款注册表单实例
2013/04/17 HTML / CSS
世界上最大的网络主机公司:1&1
2016/10/12 全球购物
介绍一下UNIX启动过程
2013/11/14 面试题
实习鉴定评语
2014/01/19 职场文书
常务副县长“四风”个人对照检查材料思想汇报
2014/10/02 职场文书
民事上诉状范文
2015/05/22 职场文书
推荐六本经典文学奖书籍:此生必读
2019/08/22 职场文书
Java Spring 控制反转(IOC)容器详解
2021/10/05 Java/Android