Node.js从无到有-No-6(HTTP小爬虫)

1、HTTP爬虫

1、在node的http模块中有get和request连个接口来完成数据的获取或者提交,对于get和request我们可以去官网先看看这两个方法http://nodejs.cn/api/http.html#http_http_methods,这两个方法我们在后面的博客中还会提到。现在我们来做个爬虫来爬https://www.imooc.com/learn/348

2、首先我们要去获得该页面的html源码

var  http = require('http');
var url='http://www.imooc.com/learn/348';

http.get(url,function(res){
    var html='';
    res.on('data',function(data){    //将data事件绑定到匿名函数,data事件实际上在重复着发生,这个function实际也在重复的进行
        html+=data;                  //将获得的数据不断添加到html变量中
    })
    res.on('end',function(){         //在响应结束的事件发生后,绑定到匿名函数中,匿名函数负责打印所有的html代码
        console.log(html)   //输出一堆html的代码
    })
}).on('error',function(){
    console.log('获取课程数据出现了错误')
})

3、我们获得到网页的html源码其实没有多大用,现在我们搞点有用的数据,我们这里要获取这个网页上的课程信息,把课程列表获取下来。这里我们首先推荐cheerio模块,能够操作装载后的html,简单方便,我们使用 npm install cheerio来下载这个模块,下面我们直接亮出全部代码和两幅html网页源码图,然后我们慢慢讲解,代码按照注释的数字顺序去读

var http = require('http');
var cheerio=require('cheerio');
var url='http://www.imooc.com/learn/348';

function filterChapters(html){
    var $=cheerio.load(html)              //(2)使用cheerio模块将html代码装载进来
    var chapters=$('.chapter')            //图1告诉我们,课程的章节都在<div class="chapter course-wrap">..<div>中,我们就找到所有的chapter类,把它们放在变量chapters中,那变量chapters实际上就是个数组
    //我们期望的最后拿到的数据结构
    // [{
    //     chapterTitle:'',   //章节的标题
    //     videos:[
    //         title:'',
    //         id:'',
    //     ]
    // }]
    var courseData=[]
    chapters.each(function(item){    //在之前拿到每一章的条件下进行遍历
        var chapter=$(this)          //遍历的里面拿到单独的某一章
        var chapterTitle=chapter.find('h3').text() //图2告诉我们,每一章的大标题都在h3标签里,使用find找到h3这个标签,将h3下的文本内容使用text()拿出来
        var videos=chapter.find('.video').children('li') //videos是个数组,在本章节有几个视频,这个videos数组里就有几个元素
        var chapterData={
            chapterTitle:chapterTitle,
            videos:[]
        }
        videos.each(function(item){    
            var video=$(this).find('.J-media-item')        //图2告诉我们每个视频标题都包含在<a href='xxx' class='J-media-item'>下
            var videoTitle=video.text()                    //找到每节的视频标题
            var id=video.attr('href').split('video/')[1]   //在href=/video/6649中只截取6649
            chapterData.videos.push({
                title:videoTitle,
                id:id,
            })
        })
        courseData.push(chapterData)
    })
    return courseData;
}

function printCourseInfo(courseDate){       //(3)把获取的信息全部打印出来
    courseDate.forEach(function(item){
        var chapterTitle=item.chapterTitle
        //console.log(chapterTitle+'\n')
        console.log(chapterTitle)
        item.videos.forEach(function(video){
            console.log('['+video.id+']'+video.title+'\n')
        })
    })
}

http.get(url,function(res){                  //(1)使用get方法从我们指定的url上去获取数据
    var html='';
    res.on('data',function(data){            //将data事件和匿名函数绑定
        html+=data;                          //每次获取的数据都加到html变量中
    })
    res.on('end',function(){                 //将响应结束事件和匿名函数绑定
        var courseDate=filterChapters(html)  //最后的变量html就是从url上获取的html源码,交给filterChapters处理
        printCourseInfo(courseDate)
    })
}).on('error',function(){
    console.log('获取课程数据出现了错误')
})

4、值得注意的是,对于同一个网页在不同时间段的html源代码不一样的,所以假如代码是18年六月写的,没准到下一年就不能用了,因为网页源代码变了,结构变了,所以最后按照上的代码的思路去自己爬爬,下面展示一下上面代码运行的结果


猜你喜欢

转载自blog.csdn.net/weixin_37968345/article/details/80771495