Node.js+jade抓取博客所有文章生成靜態(tài)html文件的實(shí)例
這篇文章,我們就把上文中采集到的所有文章列表的信息整理一下,開始采集文章并且生成靜態(tài)html文件了.先看下我的采集效果,我的博客目前77篇文章,1分鐘不到就全部采集生成完畢了,這里我截了部分的圖片,文件名用文章的id生成的,生成的文章,我寫了一個簡單的靜態(tài)模板,所有的文章都是根據(jù)這個模板生成的.
項目結(jié)構(gòu):



好了,接下來,我們就來講解下,這篇文章主要實(shí)現(xiàn)的功能:
1,抓取文章,主要抓取文章的標(biāo)題,內(nèi)容,超鏈接,文章id(用于生成靜態(tài)html文件)
2,根據(jù)jade模板生成html文件
一、抓取文章如何實(shí)現(xiàn)?
非常簡單,跟上文抓取文章列表的實(shí)現(xiàn)差不多
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() );
} );
});
});
}
參數(shù)url就是文章的地址,把文章的內(nèi)容抓取完畢之后,調(diào)用filterArticle( html ) 過濾出需要的文章信息(id, 標(biāo)題,超鏈接,內(nèi)容),然后用jade的renderFile這個api,實(shí)現(xiàn)模板內(nèi)容的替換,
模板內(nèi)容替換完之后,肯定就需要生成html文件了, 所以用writeFile寫入文件,寫入文件時候,用id作為html文件名稱。這就是生成一篇靜態(tài)html文件的實(shí)現(xiàn),
接下來就是循環(huán)生成靜態(tài)html文件了, 就是下面這行:
if ( aUrl.length ) crawlerArc( aUrl.shift() );
aUrl保存的是我的博客所有文章的url, 每次采集完一篇文章之后,就把當(dāng)前文章的url刪除,讓下一篇文章的url出來,繼續(xù)采集
完整的實(shí)現(xiàn)代碼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 版權(quán)所有 - by ghostwu
后續(xù)的打算:
1,采用mongodb入庫
2,支持?jǐn)帱c(diǎn)采集
3,采集圖片
4,采集小說
等等....
以上這篇Node.js+jade抓取博客所有文章生成靜態(tài)html文件的實(shí)例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
node.js連接mongoose數(shù)據(jù)庫方法詳解
之前我們都是通過shell來完成對數(shù)據(jù)庫的各種操作的,在開發(fā)中大部分時候我們都需要通過程序來完成對數(shù)據(jù)庫的操作。而Mongoose就是一個讓我們可以通過Node來操作MongoDB的模塊2022-08-08
iOS + node.js使用Socket.IO框架進(jìn)行實(shí)時通信示例
本篇文章主要介紹了iOS + node.js使用Socket.IO框架進(jìn)行實(shí)時通信示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-04-04

