nodejs 爬虫
参考了各位大大的,然后自己写了个爬虫
用到的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 爬虫的更多相关文章
- NodeJS 爬虫爬取LOL英雄联盟的英雄信息,批量下载英雄壁纸
工欲善其事,必先利其器,会用各种模块非常重要. 1.模块使用 (1)superagent:Nodejs中的http请求库(每个语言都有无数个,java的okhttp,OC的afnetworking) ...
- Nodejs爬虫进阶教程之异步并发控制
Nodejs爬虫进阶教程之异步并发控制 之前写了个现在看来很不完美的小爬虫,很多地方没有处理好,比如说在知乎点开一个问题的时候,它的所有回答并不是全部加载好了的,当你拉到回答的尾部时,点击加载更多,回 ...
- NodeJS爬虫系统初探
NodeJS爬虫系统 NodeJS爬虫系统 0. 概论 爬虫是一种自动获取网页内容的程序.是搜索引擎的重要组成部分,因此搜索引擎优化很大程度上是针对爬虫而做出的优化. robots.txt是一个文本文 ...
- nodejs爬虫——汽车之家所有车型数据
应用介绍 项目Github地址:https://github.com/iNuanfeng/node-spider/ nodejs爬虫,爬取汽车之家(http://www.autohome.com.cn ...
- nodejs爬虫笔记(三)---爬取YouTube网站上的视频信息
思路:通过笔记(二)中代理的设置,已经可以对YouTube的信息进行爬取了,这几天想着爬取网站下的视频信息.通过分析YouTube,发现可以从订阅号入手,先选择几个订阅号,然后爬取订阅号里面的视频分类 ...
- nodejs爬虫笔记(二)---代理设置
node爬虫代理设置 最近想爬取YouTube上面的视频信息,利用nodejs爬虫笔记(一)的方法,代码和错误如下 var request = require('request'); var chee ...
- 【nodeJS爬虫】前端爬虫系列
写这篇 blog 其实一开始我是拒绝的,因为爬虫爬的就是cnblog博客园.搞不好编辑看到了就把我的账号给封了:). 言归正传,前端同学可能向来对爬虫不是很感冒,觉得爬虫需要用偏后端的语言,诸如 ph ...
- 简单实现nodejs爬虫工具
约30行代码实现一个简单nodejs爬虫工具,定时抓取网页数据. 使用npm模块 request---简单http请求客户端.(轻量级) fs---nodejs文件模块. index.js var ...
- 第一个nodejs爬虫:爬取豆瓣电影图片
第一个nodejs爬虫:爬取豆瓣电影图片存入本地: 首先在命令行下 npm install request cheerio express -save; 代码: var http = require( ...
- nodejs爬虫如何设置动态ip以及userAgent
nodejs爬虫如何设置动态ip以及userAgent 转https://blog.csdn.net/u014374031/article/details/78833765 前言 在写nodejs爬虫 ...
随机推荐
- Spring Boot整合实战Spring Security JWT权限鉴权系统
目前流行的前后端分离让Java程序员可以更加专注的做好后台业务逻辑的功能实现,提供如返回Json格式的数据接口就可以.像以前做项目的安全认证基于 session 的登录拦截,属于后端全栈式的开发的模式 ...
- [HNOI2011]数学作业 矩阵快速幂 BZOJ 2326
题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 NNN 和 MMM ,要求计算Concatenate(1..N) Concatenate (1 .. N) ...
- 【分享】利用WMITool解决浏览器主页被hao123劫持问题
我在别处发的帖子 http://www.52pojie.cn/thread-607115-1-1.html
- 非关系型数据库---Memcached
一.概述 1.Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载: 2.Memcached通过 在内存中缓存对象和数据 来减少读取数据库的次数,从而提升网站的 ...
- 033 Search in Rotated Sorted Array 搜索旋转排序数组
假设按照升序排序的数组在预先未知的某个关键点上旋转.(即 0 1 2 4 5 6 7 将变成 4 5 6 7 0 1 2).给你一个目标值来搜索,如果数组中存在这个数则返回它的索引,否则返回 -1.你 ...
- (转)CentOS 7系统详细开机启动流程和关机流程
CentOS 7系统详细开机启动流程和关机流程 原文:http://blog.csdn.net/yuesichiu/article/details/51350654 名称 bootup - 系统启动流 ...
- python 多继承(新式类) 四
转载自:http://blog.sina.com.cn/s/blog_45ac0d0a01018488.html mro即method resolution order,主要用于在多继承时判断调的属性 ...
- 行高:line-height图文解析
行高——line-height 初入前端的时候觉得CSS知道display.position.float就可以在布局上游刃有余了,随着以后工作问题层出不穷,才逐渐了解到CSS并不是几个style属性那 ...
- 北航oo作业第四单元小结
1.总结本单元两次作业的架构设计 在我动手开始总结我的设计之前,我看了其他同学已经提交在班级群里的博客,不禁汗颜,我是真的偷懒.其他同学大多使用了新建一个类,用以储存每一个UMLelemet元素的具体 ...
- hibernate课程 初探单表映射1-2 ORM定义
1 什么是ORM? ORM(Object / RelationShip Mapping) 对象/关系映射 面向对象编程(OOP)最终要把对象信息保存在关系性数据库中,要写好多sql语句.这与面向对象编 ...