這是啥情況
為毛我的運行結果是這樣的,沒有下文了。源碼如下:
var?http?=?require('http') var?Promise?=?require('bluebird') var?cheerio?=?require('cheerio') var?baseUrl?=?'http://www.xianlaiwan.cn/learn/348' var?videoIds?=?[348,?259,?197,?134,75] function?filterChapters(html)?{ var?$?=?cheerio.load(html) var?chapters?=?$('.chapter') var?title?=?$('#main?.path?a?span').text() var?number?=?parseInt($('.js-learn-num').text().trim(),?10) //?預期的整理過后的數據 /*var?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(courseData)?{ courseData.forEach(function?(coursesData)?{ console.log(courseData.number?+?'人學過'?+?courseData.title?+?'\n'); }) courseData.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()?{ 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)?{ //?對拿到的html頁面進行解析 var?courses?=?filterChapters(html) coursesData.push(courses) }) coursesData.sort(function?(a,?b)?{ return?a.number?<?b.number }) printCourseInfo })
2017-10-06
參考:http://www.xianlaiwan.cn/qadetail/238634,
這里面的代碼是可以運行的,記住 npm?install 依賴插件
2017-08-05
var?baseUrl?=?'http://www.xianlaiwan.cn/learn/348',有點問題,
改成var?baseUrl?=?'http://www.xianlaiwan.cn/learn/'
var?number?=?parseInt($('.js-learn-num').text().trim(),?10),文檔結構發生變化,里面已經不再是字符串了,不需要轉化。
原理上改為var number = $('#main .statics .js-learn-num').text();但因為number為異步加載,所以獲取不到
你那個printCourseInfo函數有問題,主要是courseData的單復數問題(coursesData還是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');
? ? ? ? ? ?})
? ? ? ?})
? ?})
}
Promise里也有點小問題,改成如下:
Promise
? ?.all(fetchCourseArray)
? ?.then(function (pages) {
? ? ? ?// 對爬取到的信息進行加工處理
? ? ? ?var coursesData = [];
? ? ? ?pages.forEach(function (html) {
? ? ? ? ? ?// 對拿到的html頁面進行解析
? ? ? ? ? ?var courses = filterChapters(html);
? ? ? ? ? ?coursesData.push(courses);
? ? ? ?})
? ? ? ?coursesData.sort(function (a, b) {
? ? ? ? ? ?return a.number < b.number;
? ? ? ?})
? ? ? ?printCourseInfo(coursesData);
? ?})
整體代碼如下(在你的基礎上改的):
var http = require('http');
var cheerio = require('cheerio');
var Promise = require('bluebird');
var baseUrl = 'http://www.xianlaiwan.cn/learn/';
var videoIds = [348, 259, 197, 134,75];
function filterChapters(html) {
? ?var $ = cheerio.load(html);
? ?var chapters = $('.chapter');
? ?var title = $('#main .path a span').text();
? ?var number = $('.js-learn-num').text();
? ?// 預期的整理過后的數據
? ?/*var 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().replace(/\s/g, "");
? ? ? ?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/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) {
? ? ? ? ? ?// 對拿到的html頁面進行解析
? ? ? ? ? ?var courses = filterChapters(html);
? ? ? ? ? ?coursesData.push(courses);
? ? ? ?})
? ? ? ?coursesData.sort(function (a, b) {
? ? ? ? ? ?return a.number < b.number;
? ? ? ?})
? ? ? ?printCourseInfo(coursesData);
? ?})
2017-07-20
發源碼阿,這個情況太多了不打印信息的話