一,缘起
由于菩提眼网站(http://www.putiyan.com)的搭建,需要将菩提眼新浪微博上(http://blog.sina.com.cn/baoqie)的内容迁移过来。
二,首先,搭建nodejs环境。
可以去nodejs官网来下载nodejs并安装http://nodejs.cn/。
三,其次,搭建html静态服务器。
通过npm安装http模块 npm install http
var http = require("http");
http.createServer(function(req, res){
// 设置字符编码(去掉中文会乱码)
res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});
res.write('hello nodeJs');
res.end();
}).linsten(3000);
四,安装爬虫依赖(superagent超级代理,cheerio,eventproxy事件代理服务器,async异步流程控制,fs(File System))
安装 npm install superagent; npm install cheerio; npm install eventproxy;
npm install async; npm install fs;
var http = require("http"),
fs = require('fs'),
superagent = require("superagent"),
cheerio = require("cheerio"),
async = require("async"),
eventproxy = require('eventproxy');
var ep = new eventproxy(),
catchFirstUrl = 'http://www.cnblogs.com/', //入口页面
pageNum = 16, //要爬取文章的页数
pageUrls = [], //存放收集文章页面网站
startDate = new Date(), //开始时间
endDate = false; //结束时间
blogArrs = {
"title": "",
"content": "",
"time": ""
},
blogArrs = [];
//存储需要的爬的列表页面
for(var i=11 ; i<= 16 ; i++){
pageUrls.push('http://blog.sina.com.cn/s/articlelist_1392517237_0_' + i + '.html');
}
// 主start程序
function start(){
function onRequest(req, res){
// 设置字符编码(去掉中文会乱码)
res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});
// 当所有 'BlogArticleHtml' 事件完成后的回调触发下面事件
ep.after('BlogArticleHtml', pageUrls.length*20, function(articleUrls){
// 获取 BlogPageUrl 页面内所有文章链接
for(var i = 0 ; i < articleUrls.length ; i++){
res.write(articleUrls[i] +'<br/>');
}
console.log('articleUrls.length is'+ articleUrls.length +',content is :'+articleUrls);
// 控制并发数
var curCount = 0;
var reptileMove = function(url,callback){
// 延迟毫秒数
var delay = parseInt((Math.random() * 30000000) % 1000, 10);
curCount++;
console.log('现在的并发数是', curCount, ',正在抓取的是', url, ',耗时' + delay + '毫秒');
superagent.get(url)
.end(function(err,sres){
// 常规的错误处理
if (err) {
console.log(err);
return;
}
//sres.text 里面存储着请求返回的 html 内容
var $ = cheerio.load(sres.text);
blogArr = {
"title": $('.titName').html(),
"content": $('.articalContent').html(),
"time": $('.articalTitle').find('.time').html().replace('(','').replace(')','')
}
blogArrs.unshift(blogArr);
});
setTimeout(function() {
curCount--;
callback(null,url +'Call back content');
}, delay);
};
// 使用async控制异步抓取
// mapLimit(arr, limit, iterator, [callback])
// 异步回调
async.mapLimit(articleUrls, 5 ,function (url, callback) {
reptileMove(url, callback);
}, function (err,result) {
endDate = new Date();
console.log('final:');
console.log(result);
for(var i = 0; i < blogArrs.length; i++){
// 生成所需要的html代码
var blogHtml = '<item>'
+'<title>' + blogArrs[i].title +'</title>'
+'<pubDate>Thu, 28 Apr 2016 11:17:16 +0000</pubDate>'
+'<dc:creator><![CDATA[admin]]></dc:creator>'
+'<content:encoded><![CDATA['+ blogArrs[i].content +']]></content:encoded>'
+'<wp:post_date><![CDATA['+ blogArrs[i].time +']]></wp:post_date>'
+'<wp:comment_status><![CDATA[open]]></wp:comment_status>'
+'<wp:ping_status><![CDATA[open]]></wp:ping_status>'
+'<wp:post_name><![CDATA[70]]></wp:post_name>'
+'<wp:status><![CDATA[publish]]></wp:status>'
+'<wp:post_type><![CDATA[post]]></wp:post_type>'
+'<wp:post_password><![CDATA[]]></wp:post_password>'
+'<wp:is_sticky>0</wp:is_sticky>'
+'</item>';
// 往result.html中追加生成的代码
fs.appendFile('result.html', blogHtml, function () {
console.log('追加内容完成');
});
}
res.write(''+ blogHtml)
//统计结果
res.write('<br/>');
res.write('<br/>');
res.write('/**<br/>');
res.write(' * 爬虫统计结果<br/>');
res.write('**/<br/>');
res.write('1、爬虫开始时间:'+ startDate +'<br/>');
res.write('2、爬虫结束时间:'+ endDate +'<br/>');
res.write('3、耗时:'+ (endDate - startDate) +'ms' +' --> '+ (Math.round((endDate - startDate)/1000/60*100)/100) +'min <br/>');
res.write('4、爬虫遍历的文章数目:'+ pageNum*20 +'<br/>');
});
});
// 轮询 所有文章列表页
pageUrls.forEach(function(pageUrl){
superagent.get(pageUrl)
.end(function(err, pres){
console.log('fetch ' + pageUrl + ' successful');
res.write('fetch ' + pageUrl + ' successful<br/>');
// 常规的错误处理
if (err) { console.log(err); }
// pres.text 里面存储着请求返回的 html 内容,将它传给 cheerio.load 之后
// 就可以得到一个实现了 jquery 接口的变量,我们习惯性地将它命名为 `$`
// 剩下就都是 jquery 的内容了
var $ = cheerio.load(pres.text);
var curPageUrls = $('.articleCell');
for(var i = 0 ; i < curPageUrls.length ; i++){
var articleUrl = curPageUrls.eq(i).find('a').attr('href');
// 相当于一个计数器
ep.emit('BlogArticleHtml', articleUrl);
}
});
})
}
http.createServer(onRequest).listen(3000);
}
exports.start= start;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。