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

用到的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. 3、kvm配置vnc

    配置kvm通过vnc访问 virsh edit privi-server 添加如下配置: <graphics type='vnc' port='5901' autoport='no' liste ...

  2. CountDownLatch与CyclicBarrier的使用与区别

    CountDownLatch的介绍和使用: 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 co ...

  3. js中的onclick事件传参需要注意的问题

    如果参数是数值类型可以直接传,如果是字符串类型需要在字符串前后加上双引号,双引号需要转义 如 onclick="test(0)";  直接传值 参数为数值 onclick=&quo ...

  4. 【Java】在eclipse中使用gradle进行项目构建 入门篇

    ##Gradle的安装与配置- Gradle 是以 Groovy 语言为基础,面向Java应用为主,基于DSL(领域特定语言)语法的自动化构建工具. 系统环境变量中添加gradle 前往官网下载Com ...

  5. 织梦通过 phpmyadmin 导出的数据,再次导入的时候报错

    错误提示: #1291 – Column 'nature' has duplicated value '婆婆妈妈' in SET SQL 查询: -- -- 导出表中的数据 `dede_member_ ...

  6. SpringBoot | 番外:使用小技巧合集

    前言 最近工作比较忙,事情也比较多.加班回到家都十点多了,洗个澡就想睡觉了.所以为了不断更太多天,偷懒写个小技巧合集吧.之后有时间都会进行文章更新的.原创不易,码字不易,还希望大家多多支持!话不多说, ...

  7. Java中的continue语句——通过示例学习Java编程(12)

    作者:CHAITANYA SINGH 来源:https://www.koofun.com//pro/kfpostsdetail?kfpostsid=23 continue语句主要是用在循环代码块中.当 ...

  8. 实现一个Promise.all

    用js自己实现一个Promise.all let promiseAll = (promises) => { return new Promise((resolve, reject) => ...

  9. Java图形界面开发—简易登录注册小程序

    登录注册小代码,将学过的一些小知识融合在一起进行了使用,加深印象.本例中如果有注释不详细的地方,详见其它博客. Java程序操作数据库SQLserver详解 功能介绍:简单的登录注册系统,使用了数据库 ...

  10. 【Linux/Ubuntu学习 10】unbuntu 下 eclipse 中文乱码的解决

    wangdd@wdd-pc:~$ gedit /var/lib/locales/supported.d/local 添加: zh_CN.GBK GBK zh_CN.GB2312 GB2312 终端执行 ...