nodejs 小爬虫(二)

上一篇是对单一页面的数据,所以只能爬到单一的数据,因为不同的 ID 请求出不同的数据,所以把小爬虫完善一下

该例子是拿幕课网中的某个页面来进行测试

这个时候就用到一个 Promise 异步回调模块(作用是把页面一个接一个的请求),node 版本比较新的就直接 require 进来就可以了,而旧版本的可以下载 bluebird 模块

npm install bluebird
然后require 进来就可以了   var Promise = require('bluebird');

先把要引入的东西引进来

var http = require('http');
var Promise = require('bluebird');
var cheerio = require('cheerio');
var baseUrl  = 'http://www.imooc.com/learn/';  //  http://www.imooc.com/learn/348
var videosIds = [348,637];
然后用 Promise 异步回调方法把 http.get 请求的包起来,思路是改变 ID 然后一个接一个的请求,Promise 里有一个 all 方法,该方法传进去的是一个数组,每一组就是一个方法,跑完所有的方法会返回一个数组,每组就是每次请求得到的数据

function getPageAsync(url){
	return new Promise(function(resolve , reject){
		console.log('正在爬取' + url);

		http.get( url , function(res){
			var html = '';

			res.on('data', function(data){   //监听 data 事件 , 这个时候爬的是整个的html代码;
				html += data;
			})

			res.on('end', function(res){
				//console.log(html);   //http跑完后打印出来  ,
				resolve(html)
			})
		}).on('error', function(e){
			reject(e);
			console.log('获取失败');
		})
	})
}


//把所有的请求的集中来一起
var fetchCourseArray = [];

videosIds.forEach(function(id){
	fetchCourseArray.push(getPageAsync(baseUrl + id));
})

Promise
	.all(fetchCourseArray)   // all 参数是一个方法的数组,  先把一堆 getPageAsync 请求给做完
	.then(function(pages){    //用了 all后 pages 是一个数组,每组是每次请求后得到的东西
		var courseData = [];
		//console.log(pages)
		pages.forEach(function(html){
			var course = filterChapters(html);

			courseData.push(course);
		})
		printCourseInfo(courseData)
	})

filterChapters  方法是把 html数据解析出有用的东西
function filterChapters(html){
	var $ = cheerio.load(html);  //拿到html 内容,然后就可以用 $('.xx') 来获取元素一样操作
	var chapter = $(".chapter");
	/*
		把有用的数据筛选成这个的结构
	{
		title : '',
		num : '',
		list : [{
			chapterTitle : '', //标题
			videos : [
				id : '',
				title : '',
			]
		}],
	}
	*/
	var title = $('.course-infos .clearfix h2').text().trim();
	var courseData = {
			title : title,
			list : [],
		}
		chapter.each(function(item){
			var chapter = $(this);
			var videos = chapter.find('.video').children('li');
			var chapterTitle = chapter.find('strong').text().trim();

			var list = {
					chapterTitle : chapterTitle,
					videos : [],
				}
				videos.each(function(item){
					var video = $(this).find('.J-media-item');
					var videoTitle = video.text();
					var id = videos.attr('data-media-id');

						list.videos.push({
							id : id,
							title : videoTitle,
						})
				})

				courseData.list.push(list);
		})

		return courseData;
}

printCourseInfo 方法是打得到的数据打印出来

function printCourseInfo(courseData){
	courseData.forEach(function(data){
		var pageTitle = data.title;
		console.log(pageTitle + '\n');    //页面标题
		data.list.forEach(function(item){
			var title = item.chapterTitle;
			var videos = item.videos;
				console.log(title + '\n'); //第N章节标题

				videos.forEach(function(video){
					console.log('【'+video.id+'】' + video.title + '\n');  //内容
				})


		})
	})	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值