参考了各位大大的,然后自己写了个爬虫

用到的modules:
utils.js        ---    moment

module_url.js    
  var http = require("http");         //获得页面数据
  var cheerio = require("cheerio");     //分析页面数据,提取内容
  var sanitize = require("validator");     //过滤没用的数据 如空格等  
  var fs = require('fs');          //操作文件,保存结果  

app.js 

  var async = require("async");    //异步操作 如each, filter
  var ts = require("timespans")    //计算花费时间
  var sanitize = require("validator");  //过滤没用的数据 如空格等

获得每个页面的话题列表       --   并行的
根据话题列表获得的话题具体内容   --   并行的  但是最后输出的内容是按顺序的

别处拷来的utils  里面重写了下console.log  增加了输出的时间

var moment = require('moment');

exports.inc = function(n, callback, timeout) {
timeout = timeout || 200;
setTimeout(function() {
callback(null, n+1);
}, timeout);
}; exports.fire = function(obj, callback, timeout) {
timeout = timeout || 200;
setTimeout(function() {
callback(null, obj);
}, timeout);
}; exports.err = function(errMsg, callback, timeout) {
timeout = timeout || 200;
setTimeout(function() {
callback(errMsg);
}, timeout);
}; // utils
exports.log = function(msg, obj) {
process.stdout.write(moment().format('ss.SSS')+'> ');
if(obj!==undefined) {
process.stdout.write(msg);
console.log(obj);
} else {
console.log(msg);
}
}; exports.wait = function(mils) {
var now = new Date;
while(new Date - now <= mils);
}

utils.js

抓取页面数据

//获得页面数据
var http = require("http");
//分析页面数据,提前内容
var cheerio = require("cheerio");
//过滤没用的数据 如空格等
var sanitize = require("validator");
//操作文件,保存结果
var fs = require('fs'); var scrapy = {};
scrapy.get = function(url, callback) {
http.get(url, function(res) { var size = 0;
var chunks = []; res.on('data', function(chunk) {
size += chunk.length;
chunks.push(chunk);
}); res.on('end', function() {
var data = Buffer.concat(chunks, size);
callback(null, data);
}); }).on('error', function(e) {
callback(e, null);
});
} var getPage = function(pageUrl, callback){
scrapy.get(pageUrl, function(err, data){
if(err){
callback(err);
} var html = data.toString();
$ = cheerio.load(html);
//title link, link to detail page
var news = $('.cell .topic_title_wrapper a');
callback(null, news);
});
} var getDetail = function(detailUrl, callback){
scrapy.get(detailUrl, function(err, data){
if(err){
callback(err);
} var html = data.toString();
$ = cheerio.load(html);
var item = {};
item.href = detailUrl;
$('.header .topic_full_title .put_top').remove(); //删除 “置顶”
item.title = sanitize.escape(sanitize.trim($('.header .topic_full_title').text()));
item.content = sanitize.escape(sanitize.trim($('.inner.topic .topic_content').text())); callback(null, item);
});
} var save = function(fileName, data) {
var result = JSON.stringify(data);
fs.writeFileSync(fileName, result);
} exports.getUrl = scrapy.get;
exports.getPage = getPage;
exports.getDetail = getDetail;
exports.save = save;

module_url.js

主文件

//自定义console.log 加入了输出时间
var utils = require("./utils");
var log = utils.log;
//异步操作 如each, filter
var async = require("async");
//计算花费时间
var ts = require("timespans")
//过滤没用的数据 如空格等
var sanitize = require("validator");
var url = require("./module_url") var baseUrl = 'http://cnodejs.org';
var pageUrl = baseUrl + '/?page=';
var isOnlyTitle = true;
var pages = [];
for (var i = 1; i < 4; i++) {
pages.push(i);
}; ts.start();
var titles = {};
//page 之间并行
async.forEach(pages, function(page, callback_each){
titles[page] = []; url.getPage(pageUrl + page, function(err, news){
if(err){
log("page error");
return;
} if (news.length === 0) {
log("no data for the page:" + page);
return;
} async.filter(news, function(index, callback){
var detailUrl = baseUrl + news[index].attribs['href']; if(isOnlyTitle){
var curNew = news[index];
var item = {};
item.href = detailUrl;
$(curNew).find(".put_top").remove(); //删除 “置顶”
item.title = sanitize.escape(sanitize.trim($(curNew).text())); titles[page][index] = item; callback(true);
}
else{
url.getDetail(detailUrl, function(err, item){
if(err){
log("detail error");
return;
}
titles[page][index] = item;
//titles[page].push(item); callback(true);
});
}
}, function(result){
//log("filter news:", result);
callback_each(null);
}); });
}, function(err){
ts.stop();
//ts.pause(); --- ts.continue();
console.log('total: %s pause: %s used: %s', ts.elapsedtime(), ts.pausetime(), ts.usedtime());
log(titles);
//url.save("cnodejs.json", titles);
});

app.js

另外:想实现抓取某个时间段内的话题,努力ing...

nodejs 爬虫的更多相关文章

  1. NodeJS 爬虫爬取LOL英雄联盟的英雄信息,批量下载英雄壁纸

    工欲善其事,必先利其器,会用各种模块非常重要. 1.模块使用 (1)superagent:Nodejs中的http请求库(每个语言都有无数个,java的okhttp,OC的afnetworking) ...

  2. Nodejs爬虫进阶教程之异步并发控制

    Nodejs爬虫进阶教程之异步并发控制 之前写了个现在看来很不完美的小爬虫,很多地方没有处理好,比如说在知乎点开一个问题的时候,它的所有回答并不是全部加载好了的,当你拉到回答的尾部时,点击加载更多,回 ...

  3. NodeJS爬虫系统初探

    NodeJS爬虫系统 NodeJS爬虫系统 0. 概论 爬虫是一种自动获取网页内容的程序.是搜索引擎的重要组成部分,因此搜索引擎优化很大程度上是针对爬虫而做出的优化. robots.txt是一个文本文 ...

  4. nodejs爬虫——汽车之家所有车型数据

    应用介绍 项目Github地址:https://github.com/iNuanfeng/node-spider/ nodejs爬虫,爬取汽车之家(http://www.autohome.com.cn ...

  5. nodejs爬虫笔记(三)---爬取YouTube网站上的视频信息

    思路:通过笔记(二)中代理的设置,已经可以对YouTube的信息进行爬取了,这几天想着爬取网站下的视频信息.通过分析YouTube,发现可以从订阅号入手,先选择几个订阅号,然后爬取订阅号里面的视频分类 ...

  6. nodejs爬虫笔记(二)---代理设置

    node爬虫代理设置 最近想爬取YouTube上面的视频信息,利用nodejs爬虫笔记(一)的方法,代码和错误如下 var request = require('request'); var chee ...

  7. 【nodeJS爬虫】前端爬虫系列

    写这篇 blog 其实一开始我是拒绝的,因为爬虫爬的就是cnblog博客园.搞不好编辑看到了就把我的账号给封了:). 言归正传,前端同学可能向来对爬虫不是很感冒,觉得爬虫需要用偏后端的语言,诸如 ph ...

  8. 简单实现nodejs爬虫工具

    约30行代码实现一个简单nodejs爬虫工具,定时抓取网页数据. 使用npm模块 request---简单http请求客户端.(轻量级) fs---nodejs文件模块.   index.js var ...

  9. 第一个nodejs爬虫:爬取豆瓣电影图片

    第一个nodejs爬虫:爬取豆瓣电影图片存入本地: 首先在命令行下 npm install request cheerio express -save; 代码: var http = require( ...

  10. nodejs爬虫如何设置动态ip以及userAgent

    nodejs爬虫如何设置动态ip以及userAgent 转https://blog.csdn.net/u014374031/article/details/78833765 前言 在写nodejs爬虫 ...

随机推荐

  1. thinkphp5 join使用注意

    A表有id,name,time等字段, B表有id,type,uid,email,address等字段. A表中的id和B表中的uid对应. Db::table(A表)->alias('a') ...

  2. thinkphp5引入百度编辑器

    在ThinkPHP的模板(html文件)中引入Ueditor  下载ueditor解压至public/static目录 在需要的页面引入js文件 <script type="text/ ...

  3. EventLoop-浏览器与Node.js--整理

    近来面试中会遇到的问题,关于浏览器和Nodejs两个运行环境的Event loop. 整理值得阅读的优秀文章 参考文章: 1.不要混淆nodejs和浏览器的eventloop 2.nodejs官网关于 ...

  4. noi省选 [九省联考2018]一双木棋题解(状压dp)

    比浙江简单多了........ 题目转送:https://www.luogu.org/problemnew/show/P4363 分析: 我们注意到n和m都很小,考虑一下状压dp. 显然,棋子摆成的形 ...

  5. JS——json、ajax、jsonp

    json: data.json: { "code":1, "data": { "name": "kid", " ...

  6. A -- A. Quailty and Playing Cards 模拟 + 思考

    http://www.ifrog.cc/acm/problem/1036?contest=1005&no=0 分类,考虑Q神出的是第一张或者是第二张,然后对手出那些牌来应付. Q神出第一张和第 ...

  7. Linux Bash 命令行快捷键小结

    编辑命令          光标移动                                                                        剪切.删除 Ctrl ...

  8. 其它电脑访问mysql被拒绝

    例如,你想myuser使用mypassword从任何主机连接到mysql服务器的话. mysql> GRANT ALL PRIVILEGES ON *.* TO 'myuser'@'%' IDE ...

  9. 来自于51CTO的经典学习资料汇总

    移动开发类: 1.2012Android开发热门资料(110个)       http://bbs.51cto.com/thread-934023-1.html 2.[绝对给力]Android开发免豆 ...

  10. pygame 使用

    模块概况 display image event key mouse font 类概况 Rect: 返回的矩阵区域(图片) Surface: 可以看做是一个贴图, 它就是来显示的 display(与显 ...