這節課的完整代碼,僅供參考(number為異步加載,所以獲取不到)
var http = require('http')
var Promise = require('bluebird')
var cheerio = require('cheerio')
var baseUrl = 'http://www.xianlaiwan.cn/learn/'
var url = 'http://www.xianlaiwan.cn/learn/348'
var videoIds = [348, 259, 197, 134, 75]
function filterChapters(html){
? ? ?var $ = cheerio.load(html);
? ? ?var chapters = $('.chapter');
? ? ?var header = $('.course-infos');
var title = $(' .pr .path span').text();
//這個人數值是瀏覽器端異步渲染的,http.get只會獲取第一次服務器返回的HTML代碼,所以這里獲取不到number
var number = parseInt($('.statics .static-item .js-learn-num').text().trim(), 10);
? ? ??
? ? ?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().replace(/(^\s+)|(\s+$)/g, "");
? ? ? ? ? ? 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 + '\n');
})
coursesData.forEach(function(courseData){
console.log('###' + courseData.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');
? ? ? ? })
? ? })
})
}
function getPageAsync(url){
return new Promise(function(resolve, reject){
console.log('正在爬取 ' + url);
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 fetchCourseArray = [];
videoIds.forEach(function(id){
fetchCourseArray.push(getPageAsync(baseUrl + id));
})
Promise
.all(fetchCourseArray)
.then(function(pages){
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);
})
2016-11-02
soga,那沒有其它方法可以獲取到number么
2016-10-10
視頻的代碼 還是有漏洞