为了账号安全,请及时绑定邮箱和手机立即绑定

node下,运行弹出错误

http://img1.sycdn.imooc.com//57e1ff070001649708320260.jpg

请问各位大神,这个问题应该怎么解决?

我试过npm init --yes了,还是不行。

下面是代码

var http = require('http');
var promise = require('bluebird');
var cheerio = require('cheerio');
var baseUrl = 'http://www.imooc.com/learn/';
var videoIds = [75,134,197,259,348,637];

function filterChapters(html){
	var $ = cheerio.load(html);
	/*var chapters = $('.mod-chapters');
	var title = $('#page_title .path span').text();
	var num = parseInt($($('.info_num i')[0]).text().trim(),10);*/

	var chapters = $('.chapter')

    var title = $('.course-infos .path span').text()

    var number = parseInt($($('.meta-value strong')[3]).text().trim(), 10)

	/*courseData = {
		title: title,
		number: number,
		videos: [{
			chapterTitle: '',
			videos:[
				title: '',
				id: ''
			]
		}]
	}
*/

	var courseData = {
		videos: [],
		number: number,
		title: []
	};
	chapters.each(function(item){
		var chapter = $(this);
		var chapterTitle = chapter.find('strong').text();
		var videos = chapter.find('.video').children('li')
		var chapterData = {
			chapterTitle: chapterTitle,
			videos:[]
		}

		videos.each(function(item){
			var video = $(this).find('.J-media-item');
			var videoTitle = video.text();
			var id = video.attr('href').split('/video/')[1];

			chapterData.videos.push({
				title: videoTitle,
				id: id
			})
		})
		courseData.push(chapterData);
	})
	return courseData;
}

function printCourseInfo(coursesData) {
	coursesData.forEach(function(courseData) {
		console.log(courseData.num + '人学过' + courseData.title + '\n');
	})

	coursesData.forEach(function(courseData) {
		console.log('###' + 'courseData.title' + '\n');
		var chapterTitle = item.chapterTitle;

		courseData.forEach(function(item) {
			console.log('###' + 'courseData.title' + '\n');
			var chapterTitle = item.chapterTitle;

			console.log(chapterTitle+'\n');

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

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

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

			res.on('data',function(data){
				html += data;
			})

			res.on('end',function(){
				resolve(html);
			})
		}).on('error',function(e){
			reject(e);
			console.log('获取课程数据出错');
		})

	})
}

var fetctCourseArray = [];

videoIds.forEach(function(id) {
	fetctCourseArray.push(getPageAsync(baseUrl + id));
})

promise
	.all([])
	.then(function(pages) {
		var courseData = [];

		pages.forEach(function(html) {
			var courses = filterChapters(html);

			courseData.push(courses);
		})

		courseData.sort(function(a,b) {
			return a.number > b.number
		})

		printCourseInfo(courseData);
	})


正在回答

2 回答

首先 promise.all(fetctCourseArray);
其次慕课网改版了,你上面的title跟number都应该获取不到数据

1 回复 有任何疑惑可以回复我~
#1

苍白的尾巴 提问者

谢谢你,我把这里改了。 但是还是报错,和前面的报错是一样的。 _bitField 是什么意思啊?promise.js 里有这个变量。
2016-09-22 回复 有任何疑惑可以回复我~
#2

甩甩是落雨 回复 苍白的尾巴 提问者

一步步console.log()输出调试,看是从哪里开始数据有问题;我也是菜鸟,正在学习中。
2016-09-23 回复 有任何疑惑可以回复我~
#3

苍白的尾巴 提问者 回复 甩甩是落雨

额,一起加油吧
2016-09-23 回复 有任何疑惑可以回复我~
#4

甩甩是落雨 回复 苍白的尾巴 提问者

courseData.forEach(function(item){第70行 courseData.videos.forEach(function(item){
2016-09-23 回复 有任何疑惑可以回复我~
#5

甩甩是落雨 回复 苍白的尾巴 提问者

命令行报错有显示的,第70行
2016-09-23 回复 有任何疑惑可以回复我~
#6

苍白的尾巴 提问者 回复 甩甩是落雨

终于找到问题了,是Promise对象的问题。谢谢你
2016-09-24 回复 有任何疑惑可以回复我~
查看3条回复

终于爬出来了。。。

//加载内置模块http的方法
var http = require('http');
//通过bluebird加载Promise对象
var Promise = require('bluebird');
//加载cheerio API
var cheerio = require('cheerio');
//为了简写,把重复的url部分放在baseUrl里,用的时候遍历一下就可以了
var baseUrl = 'http://www.imooc.com/learn/';
var videoIds = [75,134,197,259,348,637];

function filterChapters(html){
	var $ = cheerio.load(html);
    //trim()消除空格
	var chapters = $('.chapter')
    var title = $('.course-infos .w .path span').text();	
    var number = parseInt($($('.static-item .js-learn-num')).text().trim(), 10)

	/* 预想的数据结构
	courseData = {
		title: title, 课程名称
		number: number, 学习人数
		videos: [{ 
			chapterTitle: '',
			videos:[
				title: '',
				id: ''
			]
		}]
	}
	*/

	var courseData = {
		title: title,
		number: number,
		videos: []
	};
	chapters.each(function(item){
		var chapter = $(this);
		var chapterTitle = chapter.find('strong').text();
		var videos = chapter.find('.video').children('li')
		var chapterData = {
			chapterTitle: chapterTitle,
			videos: []
		}

		videos.each(function(item){
			var video = $(this).find('.J-media-item');
			var videoTitle = video.text();
			var id = video.attr('href').split('/video/')[1];

			chapterData.videos.push({
				title: videoTitle,
				id: id
			})
		})
		courseData.videos.push(chapterData);
	})
	return courseData;
}

function printCourseInfo(coursesData) {
	coursesData.forEach(function(courseData) {
		console.log(courseData.number + '人学过' + courseData.title);
	})

	coursesData.forEach(function(courseData) {
		console.log('###' + courseData.title);
		
		courseData.videos.forEach(function(item) {
			var chapterTitle = item.chapterTitle;

			console.log(chapterTitle);

			item.videos.forEach(function(video) {
				console.log(' 【'+video.id+'】'+video.title);
			})
		})
	})
	console.log('\n');
}
/*
	异步的爬取数据,传入需要爬的网站的url
*/
function getPageAsync(url) {
	return new Promise(function(resolve,reject) {
		console.log('正在爬取'+url);
		//给http模块添加get方法
		//get方法必须传入url,可以添加success方法(成功时运行的函数)
		http.get(url,function(res) {
			var html = '';
			//on()绑定事件
			//data事件是不断获取返回的数据
			res.on('data',function(data){
				//获取所有页面代码
				html += data;
			})
			//end事件是结束发送请求
			res.on('end',function(){
				//undefined
				resolve(html);
			})
		}).on('error',function(e){
			//绑定错误事件,返回错误原因
			reject(e);
			console.log('获取课程数据出错');
		})

	})
}
//Promise对象的数组
var fetctCourseArray = [];
//遍历所有的课程id(id保存在这个数组videoIds里了)
videoIds.forEach(function(id) {
	//爬到所有课程页面的源码,返回Promise对象,并保存在数组里
	fetctCourseArray.push(getPageAsync(baseUrl + id));
})
//Promise.all(),返回一个Promise对象,使传入的参数(可迭代参数,比如数组)都resolve一遍
//Promise.resolve(),解析promise对象,按照后面的.then方法解析
//.then(),链式调用
Promise
	.all(fetctCourseArray)
	.then(function(pages) {
		//存放页面解析结果
		var coursesData = [];
		//pages是课程页面
		pages.forEach(function(html) {
			//通过filterChapters解析html
			var courses = filterChapters(html);
			//把解析的结果放进coursesData[]
			coursesData.push(courses);
		})
		//由高到低排序
		coursesData.sort(function(a,b) {
			return a.number > b.number
		})
		//打印输出
		printCourseInfo(coursesData);
	})


0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
进击Node.js基础(二)
  • 参与学习       76755    人
  • 解答问题       226    个

本教程带你攻破 Nodejs,让 JavaScript流畅运行在服务器端

进入课程

node下,运行弹出错误

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信