node.js 小爬蟲抓取網頁資料(2)
阿新 • • 發佈:2019-02-10
node.js 小爬蟲抓取網頁資料
在原來的基礎上,採用了promise的模組,使其可以一次性多頁面的爬取網頁資料。
var http = require('http') var Promise = require('promise') var cheerio = require('cheerio') var baseUrl = 'http://www.imooc.com/learn/' var url = 'http://www.imooc.com/learn/348' var vedioIds = ['348','637','259','75','197'] function filterChapters(html) { var $ = cheerio.load(html) var chapters = $('.chapter') //var title = $('#main .path span').text(); var title = $('.path').children('a').children('span').text().trim() // var level = $($('.static-item.l')[1]).find('span').last().text().trim() // console.log(level) // courseData = { // title: title, // number, // videos:[{ // chapterTitle: '', // videos: [{ // title: '', // id: '' // }] // }] // } var courseData = { title: title, number: 0, videos: [] } chapters.each(function() { var chapter = $(this) // $(this)的用法可以讓回撥方法省略引數 var chapterTitle = chapter.find('strong').contents().filter(function() { return this.nodeType === 3; // 設定一個過濾器拿到文字內容 }).text().trim(); var videos = chapter.find('ul').children() var chapterData = { // 定義一個json以接收資料 chapterTitle : chapterTitle, videos : [] } videos.each(function() { var video = $(this).find('a') var temp = video.text().trim() var arr = temp.split('\n') // 多層標籤的文字都拼到一起了,要拆開,取用需要的值 var videoTitle = arr[0].trim() + ' ' + arr[1].trim() var id = video.attr('href').split('video/')[1].trim() chapterData.videos.push({ title : videoTitle, id : id }) }) courseData.videos.push(chapterData) }) return courseData } // 輸出函式 function printCoursesData(coursesData) { coursesData.forEach(function(courseData) { console.log('title: ' + courseData.title + '\n') //console.log('number: ' + courseData.number) courseData.videos.forEach(function(item) { var chapterTitle = item.chapterTitle console.log(chapterTitle) item.videos.forEach(function(vedio) { console.log('---[' + vedio.id + ']' + vedio.title.trim()) }) }) console.log('------------------------------------' + '\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) // var courseData = filterChapters(html) // printCourseData(courseData) }) }).on('error', function(e) { reject(e) console.log('獲取課程資料出錯!') }) }) } var fetchCourseArray = [] vedioIds.forEach(function(id) { fetchCourseArray.push(getPageAsync(baseUrl + id)) }) Promise .all(fetchCourseArray) .then(function(pages) { var coursesData = [] pages.forEach(function(html) { var course = filterChapters(html) coursesData.push(course) }) // coursesData.sort(function(a, b) { // return a.number < b.number // }) printCoursesData(coursesData) })