欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Node.js+jade抓取博客所有文章生成静态html文件的实例

程序员文章站 2022-09-08 14:12:08
这篇文章,我们就把上文中采集到的所有文章列表的信息整理一下,开始采集文章并且生成静态html文件了.先看下我的采集效果,我的博客目前77篇文章,1分钟不到就全部采集生成完毕...

这篇文章,我们就把上文中采集到的所有文章列表的信息整理一下,开始采集文章并且生成静态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文件的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。