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 CSS 修改学习第四章 透明度设置
Feb 19 Javascript
jquery 仿QQ校友的DIV模拟窗口效果源码
Mar 24 Javascript
关于js注册事件的常用方法
Apr 03 Javascript
JS获取文本框,下拉框,单选框的值的简单实例
Feb 26 Javascript
node.js不得不说的12点内容
Jul 14 Javascript
JavaScript性能优化之小知识总结
Nov 20 Javascript
Google 地图事件实例讲解
Aug 06 Javascript
BootStrap入门学习第一篇
Aug 28 Javascript
解决Webpack 热部署检测不到文件变化的问题
Feb 22 Javascript
Vue动态控制input的disabled属性的方法
Jun 26 Javascript
vue结合element-ui使用示例
Jan 24 Javascript
详解基于webpack&amp;gettext的前端多语言方案
Jan 29 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中error_reporting函数用法详细介绍
2017/06/11 PHP
php 根据URL下载远程图片、压缩包、pdf等文件到本地
2019/07/26 PHP
Laravel 实现在Blade模版中使用全局变量代替路径的例子
2019/10/22 PHP
JavaScript 动态改变图片大小
2009/06/11 Javascript
JS判断页面加载状态以及添加遮罩和缓冲动画的代码
2012/10/11 Javascript
用js获取电脑信息(是使用与IE浏览器)
2013/01/15 Javascript
js实现收缩菜单效果实例代码
2013/10/30 Javascript
容易造成JavaScript内存泄露几个方面
2014/09/04 Javascript
基于bootstrap实现广告轮播带图片和文字效果
2016/07/22 Javascript
javascript 判断当前浏览器版本并判断ie版本
2017/02/17 Javascript
JavaScript之面向对象_动力节点Java学院整理
2017/06/29 Javascript
vue src动态加载请求获取图片的方法
2018/10/17 Javascript
vue 左滑删除功能的示例代码
2019/01/28 Javascript
JS页面获取 session 值,作用域和闭包学习笔记
2019/10/16 Javascript
vue全屏事件开发详解
2020/06/17 Javascript
Python浅拷贝与深拷贝用法实例
2015/05/09 Python
深入理解Python中的内置常量
2017/05/20 Python
5款非常棒的Python工具
2018/01/05 Python
Python二进制串转换为通用字符串的方法
2018/07/23 Python
Python对列表的操作知识点详解
2019/08/20 Python
windows中安装Python3.8.0的实现方法
2019/11/19 Python
关于Pytorch MaxUnpool2d中size操作方式
2020/01/03 Python
如何使用python实现模拟鼠标点击
2020/01/06 Python
python3中sorted函数里cmp参数改变详解
2020/03/12 Python
详解python中的异常捕获
2020/12/15 Python
CSS3基础(RGBa、text-shadow、box-shadow、border-radius)
2012/11/13 HTML / CSS
美国专营婴幼儿用品的购物网站:buybuy BABY
2017/01/01 全球购物
保荐人的岗位职责
2013/11/19 职场文书
投标单位介绍信
2014/01/09 职场文书
公司副总经理任命书
2014/06/05 职场文书
2014领导班子四风问题查摆思想汇报
2014/09/13 职场文书
不服从上级领导安排的检讨书
2014/09/14 职场文书
2014年销售内勤工作总结
2014/12/01 职场文书
2015秋季幼儿园开学寄语
2015/03/25 职场文书
《我在为谁工作》:工作的质量往往决定生活的质量
2019/12/27 职场文书
Promise面试题详解之控制并发
2021/05/14 面试题