当前位置:Gxlcms > JavaScript > Node.js+jade抓取博客所有文章生成静态html文件的实例

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

时间:2021-07-01 10:21:17 帮助过:5人阅读

这篇文章,我们就把上文中采集到的所有文章列表的信息整理一下,开始采集文章并且生成静态html文件了.先看下我的采集效果,我的博客目前77篇文章,1分钟不到就全部采集生成完毕了,这里我截了部分的图片,文件名用文章的id生成的,生成的文章,我写了一个简单的静态模板,所有的文章都是根据这个模板生成的.

项目结构:

好了,接下来,我们就来讲解下,这篇文章主要实现的功能:

1,抓取文章,主要抓取文章的标题,内容,超链接,文章id(用于生成静态html文件)

2,根据jade模板生成html文件

一、抓取文章如何实现?

非常简单,跟上文抓取文章列表的实现差不多

  1. function crawlerArc( url ){
  2. var html = '';
  3. var str = '';
  4. var arcDetail = {};
  5. http.get(url, function (res) {
  6. res.on('data', function (chunk) {
  7. html += chunk;
  8. });
  9. res.on('end', function () {
  10. arcDetail = filterArticle( html );
  11. str = jade.renderFile('./views/layout.jade', arcDetail );
  12. fs.writeFile( './html/' + arcDetail['id'] + '.html', str, function( err ){
  13. if( err ) {
  14. console.log( err );
  15. }
  16. console.log( 'success:' + url );
  17. if ( aUrl.length ) crawlerArc( aUrl.shift() );
  18. } );
  19. });
  20. });
  21. }

参数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:

  1. var fs = require( 'fs' );
  2. var http = require( 'http' );
  3. var cheerio = require( 'cheerio' );
  4. var jade = require( 'jade' );
  5. var aList = [];
  6. var aUrl = [];
  7. function filterArticle(html) {
  8. var $ = cheerio.load( html );
  9. var arcDetail = {};
  10. var title = $( "#cb_post_title_url" ).text();
  11. var href = $( "#cb_post_title_url" ).attr( "href" );
  12. var re = /\/(\d+)\.html/;
  13. var id = href.match( re )[1];
  14. var body = $( "#cnblogs_post_body" ).html();
  15. return {
  16. id : id,
  17. title : title,
  18. href : href,
  19. body : body
  20. };
  21. }
  22. function crawlerArc( url ){
  23. var html = '';
  24. var str = '';
  25. var arcDetail = {};
  26. http.get(url, function (res) {
  27. res.on('data', function (chunk) {
  28. html += chunk;
  29. });
  30. res.on('end', function () {
  31. arcDetail = filterArticle( html );
  32. str = jade.renderFile('./views/layout.jade', arcDetail );
  33. fs.writeFile( './html/' + arcDetail['id'] + '.html', str, function( err ){
  34. if( err ) {
  35. console.log( err );
  36. }
  37. console.log( 'success:' + url );
  38. if ( aUrl.length ) crawlerArc( aUrl.shift() );
  39. } );
  40. });
  41. });
  42. }
  43. function filterHtml(html) {
  44. var $ = cheerio.load(html);
  45. var arcList = [];
  46. var aPost = $("#content").find(".post-list-item");
  47. aPost.each(function () {
  48. var ele = $(this);
  49. var title = ele.find("h2 a").text();
  50. var url = ele.find("h2 a").attr("href");
  51. ele.find(".c_b_p_desc a").remove();
  52. var entry = ele.find(".c_b_p_desc").text();
  53. ele.find("small a").remove();
  54. var listTime = ele.find("small").text();
  55. var re = /\d{4}-\d{2}-\d{2}\s*\d{2}[:]\d{2}/;
  56. listTime = listTime.match(re)[0];
  57. arcList.push({
  58. title: title,
  59. url: url,
  60. entry: entry,
  61. listTime: listTime
  62. });
  63. });
  64. return arcList;
  65. }
  66. function nextPage( html ){
  67. var $ = cheerio.load(html);
  68. var nextUrl = $("#pager a:last-child").attr('href');
  69. if ( !nextUrl ) return getArcUrl( aList );
  70. var curPage = $("#pager .current").text();
  71. if( !curPage ) curPage = 1;
  72. var nextPage = nextUrl.substring( nextUrl.indexOf( '=' ) + 1 );
  73. if ( curPage < nextPage ) crawler( nextUrl );
  74. }
  75. function crawler(url) {
  76. http.get(url, function (res) {
  77. var html = '';
  78. res.on('data', function (chunk) {
  79. html += chunk;
  80. });
  81. res.on('end', function () {
  82. aList.push( filterHtml(html) );
  83. nextPage( html );
  84. });
  85. });
  86. }
  87. function getArcUrl( arcList ){
  88. for( var key in arcList ){
  89. for( var k in arcList[key] ){
  90. aUrl.push( arcList[key][k]['url'] );
  91. }
  92. }
  93. crawlerArc( aUrl.shift() );
  94. }
  95. var url = 'http://www.cnblogs.com/ghostwu/';
  96. crawler( url );

layout.jade文件:

  1. doctype html
  2. html
  3. head
  4. meta(charset='utf-8')
  5. title jade+node.js express
  6. link(rel="stylesheet", href='./css/bower_components/bootstrap/dist/css/bootstrap.min.css')
  7. body
  8. block header
  9. div.container
  10. div.well.well-lg
  11. h3 ghostwu的博客
  12. p js高手之路
  13. block container
  14. div.container
  15. h3
  16. a(href="#{href}" rel="external nofollow" ) !{title}
  17. p !{body}
  18. block footer
  19. div.container
  20. footer 版权所有 - by ghostwu

后续的打算:

1,采用mongodb入库

2,支持断点采集

3,采集图片

4,采集小说

等等....

以上这篇Node.js+jade抓取博客所有文章生成静态html文件的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

人气教程排行