您好,欢迎访问一九零五行业门户网

爬取慕课网课程信息实例教程

第一次学习node.js爬虫,所以这时一个简单的爬虫,node.js的好处就是可以并发的执行
这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让我们方便的操作html,就像是用jq一样
开始前,记得
npm install cheerio
为了能够并发的进行爬取,用到了promise对象
//接受一个url爬取整个网页,返回一个promise对象function getpageasync(url){return new promise((resolve,reject)=>{         console.log(`正在爬取${url}的内容`);         http.get(url,function(res){             let html = '';             res.on('data',function(data){                 html += data;             });             res.on('end',function(){                 resolve(html);             });             res.on('error',function(err){                 reject(err);                 console.log('错误信息:' + err);             })         });     }) }
在慕课网中,每个课程都有一个id,我们事先要把想要获取课程的id写到一个数组中,而且每个课程的地址都是一个相同的地址加上id,所以我们只要把地址和id拼接起来就是课程的地址
const baseurl = 'http://www.imooc.com/learn/'; const basenuurl = 'http://www.imooc.com/course/ajaxcoursemembers?ids=';//获取课程的idconst videosid = [773,371];
为了使获取每个课程内容时并发执行,要使用promise中的all方法
promise//当所有网页的内容爬取完毕    .all(coursearray)     .then((pages)=>{//所有页面需要的内容let coursedata = [];//遍历每个网页提取出所需要的内容pages.foreach((html)=>{             let courses = filterchapter(html);             coursedata.push(courses);         });//给每个coursemenners.number赋值for(let i=0;i<videosid.length;i++){for(let j=0;j<videosid.length;j++){if(coursemembers[i].id +'' == videosid[j]){ coursedata[j].number = coursemembers[i].numbers; } } }//对所需要的内容进行排序coursedata.sort((a,b)=>{return a.number > b.number;         });//在重新将爬取内容写入文件中前,清空文件fs.writefilesync(outputfile,'###爬取慕课网课程信息###',(err)=>{if(err){                 console.log(err)             }         });         printfdata(coursedata);     });
在then方法中,pages是每个课程的html页面,我们还得从中提取出我们需要的信息,需要使用下面的函数
//接受一个爬取下来的网页内容,查找网页中需要的信息function filterchapter(html){     const $ = cheerio.load(html);//所有章const chapters = $('.chapter');//课程的标题和学习人数let title = $('.hd>h2').text();     let number = 0;//最后返回的数据//每个网页需要的内容的结构let coursedata = {'title':title,'number':number,'videos':[]     };     chapters.each(function(item){         let chapter = $(this);//文章标题let chaptertitle = trim(chapter.find('strong').text(),'g');//每个章节的结构let chapterdata = {'chaptertitle':chaptertitle,'video':[]         };//一个网页中的所有视频let videos = chapter.find('.video').children('li');         videos.each(function(item){//视频标题let videotitle = trim($(this).find('a.j-media-item').text(),'g');//视频idlet id = $(this).find('a').attr('href').split('video/')[1];             chapterdata.video.push({'title':videotitle,'id':id             })         });         coursedata.videos.push(chapterdata);     });return coursedata; }
注意:在上面中将课程的学习人数设置为了0是因为学习课程人数是用ajax动态获取,所以我在后面写了方法专门获取学习课程人数,其中用到的trim()方法是去除文本中的空格
获取学习课程的人数:
//获取上课人数function getnumber(url){     let datas = '';     http.get(url,(res)=>{         res.on('data',(chunk)=>{             datas += chunk;         });         res.on('end',()=>{             datas = json.parse(datas);             coursemembers.push({'id':datas.data[0].id,'numbers':parseint(datas.data[0].numbers,10)});         });     }); }
这样就将想获取课程的学习人数都添加到了coursemembers数组中,在最后将学习课程的人数在赋值给相对应的课程
        //给每个coursemenners.number赋值for(let i=0;i<videosid.length;i++){for(let j=0;j<videosid.length;j++){if(coursemembers[i].id +'' == videosid[j]){ coursedata[j].number = coursemembers[i].numbers; } } }
我们获取到了数据,就要把它按照一定的格式存到一个文件中
//写入文件function writefile(file,string) { fs.appendfilesync(file,string,(err)=>{if(err){                 console.log(err);             }         }) }//打印信息function printfdata(coursesdata){     coursesdata.foreach((coursedata)=>{       // console.log(`${coursedata.number}人学习过${coursedata.title}\n`);       writefile(outputfile,`\n\n${coursedata.number}人学习过${coursedata.title}\n\n`);         coursedata.videos.foreach(function(item){             let chaptertitle = item.chaptertitle;// console.log(chaptertitle + '\n');            writefile(outputfile,`\n  ${chaptertitle}\n`);             item.video.foreach(function(item){// console.log('     【' + item.id + '】' + item.title + '\n');                writefile(outputfile,`     【${item.id}】  ${item.title}\n`);             })         });     }); }
最后获取到的数据:
源码:
/**  * created by hp-pc on 2017/6/7 0007. */const http = require('http'); const fs = require('fs'); const cheerio = require('cheerio'); const baseurl = 'http://www.imooc.com/learn/'; const basenuurl = 'http://www.imooc.com/course/ajaxcoursemembers?ids=';//获取课程的idconst videosid = [773,371];//输出的文件const outputfile = 'test.txt';//记录学习课程的人数let coursemembers = [];//去除字符串中的空格function trim(str,is_global) {     let  result;     result = str.replace(/(^\s+)|(\s+$)/g,);if(is_global.tolowercase()==g)     {         result = result.replace(/\s/g,);     }return result; }//接受一个url爬取整个网页,返回一个promise对象function getpageasync(url){return new promise((resolve,reject)=>{         console.log(`正在爬取${url}的内容`);         http.get(url,function(res){             let html = '';             res.on('data',function(data){                 html += data;             });             res.on('end',function(){                 resolve(html);             });             res.on('error',function(err){                 reject(err);                 console.log('错误信息:' + err);             })         });     }) }//接受一个爬取下来的网页内容,查找网页中需要的信息function filterchapter(html){     const $ = cheerio.load(html);//所有章const chapters = $('.chapter');//课程的标题和学习人数let title = $('.hd>h2').text();     let number = 0;//最后返回的数据//每个网页需要的内容的结构let coursedata = {'title':title,'number':number,'videos':[]     };     chapters.each(function(item){         let chapter = $(this);//文章标题let chaptertitle = trim(chapter.find('strong').text(),'g');//每个章节的结构let chapterdata = {'chaptertitle':chaptertitle,'video':[]         };//一个网页中的所有视频let videos = chapter.find('.video').children('li');         videos.each(function(item){//视频标题let videotitle = trim($(this).find('a.j-media-item').text(),'g');//视频idlet id = $(this).find('a').attr('href').split('video/')[1];             chapterdata.video.push({'title':videotitle,'id':id             })         });         coursedata.videos.push(chapterdata);     });return coursedata; }//获取上课人数function getnumber(url){     let datas = '';     http.get(url,(res)=>{         res.on('data',(chunk)=>{             datas += chunk;         });         res.on('end',()=>{             datas = json.parse(datas);             coursemembers.push({'id':datas.data[0].id,'numbers':parseint(datas.data[0].numbers,10)});         });     }); }//写入文件function writefile(file,string) {     fs.appendfilesync(file,string,(err)=>{if(err){                 console.log(err);             }         }) }//打印信息function printfdata(coursesdata){     coursesdata.foreach((coursedata)=>{       // console.log(`${coursedata.number}人学习过${coursedata.title}\n`);       writefile(outputfile,`\n\n${coursedata.number}人学习过${coursedata.title}\n\n`);         coursedata.videos.foreach(function(item){             let chaptertitle = item.chaptertitle;// console.log(chaptertitle + '\n');            writefile(outputfile,`\n  ${chaptertitle}\n`);             item.video.foreach(function(item){// console.log('     【' + item.id + '】' + item.title + '\n');                writefile(outputfile,`     【${item.id}】  ${item.title}\n`);             })         });     }); }//所有页面爬取完后返回的promise数组let coursearray = [];//循环所有的videosid,和baseurl进行字符串拼接,爬取网页内容videosid.foreach((id)=>{//将爬取网页完毕后返回的promise对象加入数组coursearray.push(getpageasync(baseurl + id));//获取学习的人数getnumber(basenuurl + id); }); promise//当所有网页的内容爬取完毕    .all(coursearray)     .then((pages)=>{//所有页面需要的内容let coursedata = [];//遍历每个网页提取出所需要的内容pages.foreach((html)=>{             let courses = filterchapter(html);             coursedata.push(courses);         });//给每个coursemenners.number赋值for(let i=0;i<videosid.length;i++){for(let j=0;j<videosid.length;j++){if(coursemembers[i].id +'' == videosid[j]){ coursedata[j].number = coursemembers[i].numbers; } } }//对所需要的内容进行排序coursedata.sort((a,b)=>{return a.number > b.number;         });//在重新将爬取内容写入文件中前,清空文件fs.writefilesync(outputfile,'###爬取慕课网课程信息###',(err)=>{if(err){                 console.log(err)             }         });         printfdata(coursedata);     });
以上就是爬取慕课网课程信息实例教程的详细内容。
其它类似信息

推荐信息