这个周末,恶补了一下jade模板引擎,就为生成静态html文件,这篇文章需要知道jade以及看过我的上篇文章,我先给出他们的参考链接:

[js高手之路]Node.js模板引擎教程-jade速学与实战1-基本用法

[js高手之路]Node.js模板引擎教程-jade速学与实战2-流程控制,转义与非转义

[js高手之路]Node.js模板引擎教程-jade速学与实战3-mixin

[js高手之路]Node.js模板引擎教程-jade速学与实战4-模板引用,继承,插件使用

[js高手之路]Node.js实现简易的爬虫-抓取博客所有文章列表信息

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

项目结构:

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

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}") !{title}
p !{body}
block footer
div.container
footer 版权所有 - by ghostwu

后续的打算:

1,采用mongodb入库

2,支持断点采集

3,采集图片

4,采集小说

等等....

[js高手之路]Node.js+jade抓取博客所有文章生成静态html文件的更多相关文章

  1. [js高手之路]Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件

    接着这篇文章[js高手之路]Node.js+jade抓取博客所有文章生成静态html文件继续,在这篇文章中实现了采集与静态文件的生成,在实际的采集项目中, 应该是先入库再选择性的生成静态文件.那么我选 ...

  2. [js高手之路]Node.js+jade+mongoose实战todolist(分页,ajax编辑,删除)

    该系列文章索引: [js高手之路]node js系列课程-创建简易web服务器与文件读写 [js高手之路]node js系列课程-图解express+supervisor+ejs用法 [js高手之路] ...

  3. [js高手之路]Node.js实现简易的爬虫-抓取博客文章列表信息

    抓取目标:就是我自己的博客:http://www.cnblogs.com/ghostwu/ 需要实现的功能: 抓取文章标题,超链接,文章摘要,发布时间 需要用到的库: node.js自带的http库 ...

  4. [js高手之路]Node.js实现简易的爬虫-抓取博客所有文章列表信息

    抓取目标:就是我自己的博客:http://www.cnblogs.com/ghostwu/ 需要实现的功能: 抓取博客所有的文章标题,超链接,文章摘要,发布时间 需要用到的库: node.js自带的h ...

  5. [js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist

    promise主要是用来解决异步回调问题,其实还有好几种比promise更好的方案,后面再说,这节,我们先用promise来改造下,我以前写的一篇文章[js高手之路]javascript腾讯面试题学习 ...

  6. [js高手之路]Node.js模板引擎教程-jade速学与实战2-流程控制,转义与非转义

    一.转义与非转义 jade模板文件代码: doctype html html head meta(charset='utf-8') title jade学习-by ghostwu body h3 转义 ...

  7. [js高手之路]Node.js模板引擎教程-jade速学与实战1

    环境准备: 全局安装jade: npm install jade -g 初始化项目package.json: npm init --yes 安装完成之后,可以使用 jade --help 查看jade ...

  8. [js高手之路]Node.js模板引擎教程-jade速学与实战1-基本用法

    环境准备: 全局安装jade: npm install jade -g 初始化项目package.json: npm init --yes 安装完成之后,可以使用 jade --help 查看jade ...

  9. [js高手之路]node js系列课程-图解express+supervisor+ejs用法

    上文通过node js自带的http模块搭建了一个简易的服务器,实际在开发中,一般用的是express框架,本文我们就来讲讲项目开发中必备不可少的几样东西: 服务器( express ) 路由( ex ...

随机推荐

  1. 集合-TreeSet-Comparable

    Student类:name.age属性 1 package com.bjpowernode.test01_set2_Comparable; /* * T: type */ public class S ...

  2. 一篇文章学会Spring4.0

    spring概述 spring 是一个开源框架. Spring 为简化企业级应用开发而生. 使用 Spring 可以使简单的 JavaBean 实现以前只有 EJB 才能实现的功能. Spring 是 ...

  3. 如何将Windows7系统中“运行”历史记录全部清除

    如何将Windows7系统中“运行”历史记录全部清除.. 如何将Windows7系统中“运行”历史记录全部清除 1.任务栏空白处按下鼠标右键,在右键菜单栏中选择“属性”, 2.切换到“开始菜单”选项卡 ...

  4. latex 插图排版

    LaTeX的图片插入及排版   LaTeX中一般只直接支持插入eps(Encapsulated PostScript)格式的图形文件, 因此在图片插入latex文档之前应先设法得到图片的eps格式的文 ...

  5. 基本元件库(Basic)

  6. webSocket浏览器握手不成功(解决)

    websocket与服务端握手会报握手不成功的错误解决方法: 首先是服务端首次收到请求要回报给客户端的报文要做处理多的不说,方法敬上: /// <summary> /// 打包请求连接数据 ...

  7. DispatcherTimer和Timer(计时器)

    System.Windows.Threading.DispatcherTimer dTime;        System.Timers.Timer timer;        public Main ...

  8. 通过日期在js中求出判断间隔天数,周期等实现分享

    在我们在项目的时候,可能出现这样的一种情况,有一个开始时间和一个结束时间,而这两个时间用$('#StartTime').val(); 取出来的时候又是datetime 类型,我们需要求这个时间中的间隔 ...

  9. java面向对象(二)之继承

    继承 介绍 继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力.继承即常说的is-a关系.子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承 ...

  10. 源码编译安装bind

    author:JevonWei 版权声明:原创作品 编译bind 准备阶段: 下载bind软件包,然后传输到系统中 https://www.isc.org/downloads/ 安装开发包组 yum ...