运行报错:Cannot find module 'Promise'
var http = require('http');
var Promise = require('Promise');
//如果是版本比较老的,没有自带Promise,则需引入上节所说的bluebird
//var Promise = require('bluebird');
var cheerio = require('cheerio');
var baseUrl = 'https://www.imooc.com/learn/';
var url = 'https://www.imooc.com/learn/348';
var videoIds = [348, 259, 197, 134, 75];
function filterChapters(html){
//使用模块cheerio在服务器解析html代码
var $ = cheerio.load(html); //把前面的内容装载进来
var chapters = $('.chapter'); //通过类名,拿到每一大章
var title = $('.course-infos .path a span').text();
var number = $('.js-learn-num').text();
/*
* 期望得到的一个数据的结构:
* courseData = {
* title: title, //每一章节的标题
* number: number, //每个课程学习的人数
* videos:[{ //video是里面的小节,有很多视频
* chapterTitle:'', //每一小节的名字
* videos: [
* title: '',
* id: ''
* ]
* }]
* }
*/
var courseData = {
title: title,
number: number,
videos: []
};
chapters.each(function(item){
var chapter = $(this); //拿到单独的某一章
//要根据页面的代码的标签去拿
var chapterTitle = chapter.find("h3").text();
var videos = chapter.find('.video').children('li')
var chapterData = { //这一章的内容是一个对象自变量
chapterTitle: chapterTitle,
videos:[]
}
videos.each(function(item){
var video_a = $(this).find('.J-media-item');
var videoTitle = video_a.text();
var id = video_a.attr('href').split('video/')[1];
chapterData.videos.push({
title: videoTitle,
id: id
})
})
courseData.videos.push(chapterData);
})
return courseData;
}
function printCourseInfo(coursesData){
coursesData.forEach(function(courseDate){
console.log(courseDate.number + '人学过' + courseDate.title + '\n')
})
coursesData.forEach(function(courseData){
console.log('###' + coursesData.title + '\n');
courseData.videos.forEach(function(item){
var chapterTitle = item.chapterTitle;
console.log(chapterTitle + '\n')
item.videos.forEach(function(video){
console.log('【' + video.id + '】' + video.title + '\n');
})
})
})
}
/*
//运行得到页面的html源码
http.get(url, function(res){
var html = ''
res.on('data', function(data){ //有data事件触发的时候
html += data;
})
res.on("end", function(){
var courseData = filterChapters(html); //把html作为一个参数传递给一个函数,这个函数去做信息的过滤
printCourseInfo(courseData); //打印信息出来
})
}).on("error", function(){ //http注册error事件
console.log("获取课程数据出错");
})
*/
//将上面的http.get()进行promise化
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 += data;
})
res.on("end", function(){
resolve(html); //将html传递下去
//var courseData = filterChapters(html); //把html作为一个参数传递给一个函数,这个函数去做信息的过滤
//printCourseInfo(courseData); //打印信息出来
})
}).on("error", function(e){ //http注册error事件
reject(e); //爬虫出错
console.log("获取课程数据出错");
})
})
}
var fetchCourseArray = [];
videoIds.forEach(function(id){
fetchCourseArray.push(getPageAsync(baseUrl + id)); //组装之后是一个Promise对象的数组
})
//爬取多个课程里面的章节信息
Promise
.all(fetchCourseArray) //数组里就是一个一个的promise
.then(function(pages){ //通过then方法拿到传递下来的结果,多个页面的数据
//进行信息的加工
var coursesData =[];
pages.forEach(function(html){
var courses = filterChapters(html);
coursesData.push(courses)
})
//返回一个按照课程学习人数从大到小的排序
coursesData.sort(function(a, b){
return a.number < b.number;
})
printCourseInfo(coursesData);
})