Node.js+jade抓取博客所有文章生成靜態(tài)html文件的實(shí)例
這篇文章,我們就把上文中采集到的所有文章列表的信息整理一下,開始采集文章并且生成靜態(tài)html文件了.先看下我的采集效果,我的博客目前77篇文章,1分鐘不到就全部采集生成完畢了,這里我截了部分的圖片,文件名用文章的id生成的,生成的文章,我寫了一個(gè)簡單的靜態(tài)模板,所有的文章都是根據(jù)這個(gè)模板生成的.
項(xiàng)目結(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這個(gè)api,實(shí)現(xiàn)模板內(nèi)容的替換,
模板內(nèi)容替換完之后,肯定就需要生成html文件了, 所以用writeFile寫入文件,寫入文件時(shí)候,用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)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
nodejs 實(shí)現(xiàn)MQTT協(xié)議的服務(wù)器端和客戶端的雙向交互的過程
這篇文章主要介紹了nodejs 實(shí)現(xiàn)MQTT協(xié)議的服務(wù)器端和客戶端的雙向交互的過程,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-11-11Nodejs中fs文件系統(tǒng)模塊的路徑動態(tài)拼接的問題和解決方案
在使用fs模塊操作文件時(shí),如果提供的操作路徑是以./或../開頭的相對路徑時(shí),很容易出現(xiàn)路徑動態(tài)拼接錯(cuò)誤的問題,所以本文給大家介紹了Nodejs中fs文件系統(tǒng)模塊的路徑動態(tài)拼接的問題和解決方案,需要的朋友可以參考下2024-03-03實(shí)時(shí)通信WebSocket的原理和工作過程
WebSocket持久連接使得服務(wù)器可以主動向客戶端推送數(shù)據(jù),而不需要等待客戶端的請求,是一種專門設(shè)計(jì)用于實(shí)現(xiàn)持久連接的協(xié)議,WebSocket的持久連接特性使其成為實(shí)時(shí)性要求高的應(yīng)用的理想選擇,如在線聊天、實(shí)時(shí)游戲、數(shù)據(jù)監(jiān)控等2023-12-12Node.js的HTTP模塊、URL模塊與supervisor工具介紹
這篇文章介紹了Node.js的HTTP模塊、URL模塊與supervisor工具,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06