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 相关文章推荐
input 输入框内的输入事件详细分析
Mar 17 Javascript
Jquery常用技巧收集整理篇
Nov 14 Javascript
js获取网页高度(详细整理)
Dec 28 Javascript
Jquery UI震动效果实现原理及步骤
Feb 04 Javascript
JS实现遮罩层效果的简单实例
Nov 12 Javascript
动态创建script标签实现跨域资源访问的方法介绍
Feb 28 Javascript
老生常谈 js中this的指向
Jun 30 Javascript
带你快速理解javascript中的事件模型
Aug 14 Javascript
jQuery实现每隔一段时间自动更换样式的方法分析
May 03 jQuery
谈谈为什么你的 JavaScript 代码如此冗长
Jan 30 Javascript
js实现删除li标签一行内容
Apr 16 Javascript
Layui选项卡制作历史浏览记录的方法
Sep 28 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 字符串替换的方法
2012/01/10 PHP
Zend Framework使用Zend_Loader组件动态加载文件和类用法详解
2016/12/09 PHP
详解thinkphp中的volist标签
2018/01/15 PHP
基于laravel缓冲cache的用法详解
2019/10/23 PHP
JS中不为人知的五种声明Number的方式简要概述
2013/02/22 Javascript
JavaScript必知必会(六) delete in instanceof
2016/06/08 Javascript
JS 根据子网掩码,网关计算出所有IP地址范围示例
2020/04/23 Javascript
JavaScript鼠标特效大全
2016/09/13 Javascript
Bootstrap table右键功能实现方法
2017/02/20 Javascript
关于vue-router路径计算问题
2017/05/10 Javascript
Jquery的autocomplete插件用法及参数讲解
2019/03/12 jQuery
vue改变对象或数组时的刷新机制的方法总结
2019/04/24 Javascript
详解jQuery中的prop()使用方法
2020/01/05 jQuery
[00:49]完美世界DOTA2联赛10月28日开团时刻:随便打
2020/10/29 DOTA
python实现定制交互式命令行的方法
2014/07/03 Python
在Linux中通过Python脚本访问mdb数据库的方法
2015/05/06 Python
python下MySQLdb用法实例分析
2015/06/08 Python
将Python代码打包为jar软件的简单方法
2015/08/04 Python
深入剖析Python的爬虫框架Scrapy的结构与运作流程
2016/01/20 Python
使用pyecharts无法import Bar的解决方案
2020/04/23 Python
python 读取竖线分隔符的文本方法
2018/12/20 Python
python将txt文档每行内容循环插入数据库的方法
2018/12/28 Python
PyCharm安装Markdown插件的两种方法
2019/06/24 Python
python实现批量文件重命名
2019/10/31 Python
Python如何使用函数做字典的值
2019/11/30 Python
Python列表list操作相关知识小结
2020/01/29 Python
详细分析Python垃圾回收机制
2020/07/01 Python
CSS3旋转——彩色扇子兼容firefox浏览器
2013/06/04 HTML / CSS
婴儿鞋,独特的婴儿服装和配件:Zutano
2018/11/03 全球购物
P D PAOLA法国官网:西班牙著名的珠宝首饰品牌
2020/02/15 全球购物
颇特女士香港官网:NET-A-PORTER香港
2021/03/08 全球购物
大一学生假期实习的自我评价
2013/10/12 职场文书
文化宣传方案
2014/03/13 职场文书
教师党的群众路线学习心得体会
2014/11/04 职场文书
医药公司采购员岗位职责
2015/04/03 职场文书
家长会后的感想
2015/08/11 职场文书