nodejs简易爬虫

来源:互联网 发布:sql win7 64位下载 编辑:程序博客网 时间:2024/06/14 10:56

一直以来觉得爬虫这个东西很神秘很牛逼,但是又没有学过python,没有很好的学习教程。直到最近看到了Scottl老师的nodejs http爬虫的视频教学,才慢慢揭开爬虫的神秘面纱。根据老师一步一步书写代码爬取慕课网的章节信息,我对爬虫有了以下几个步骤的理解,并在此基础上完成了对熊猫Tv直播频道的爬虫程序。
首先阐述一下我认为的爬虫步骤:
1. 明确自己要爬的东西
2. 根据网页源代码,定义好相应的数据结构
3. 设计算法(笔者还没达到那个水平,只能写出很简单的算法,而且还是通过cheerio模块用的jquery语法)
4. 根据HTTP协议完成两端的通信

我的爬虫程序是用nodejs写的,因为最近在学这个东西,其中使用了express框架,以及cheerio和superagent两个模块。cheerio模块是nodejs处理html内容的神器,例如var $ = cheerio.load(html),将页面的html内容加载下来后,便可使用jquery语法进行操作,极为省力。superagent模块是http模块的升级,其链式的语法极大地方便了http方法的书写,而且代码十分整洁。
接下来看代码:

var express = require('express');var cheerio = require('cheerio');var superagent = require('superagent');var url = 'http://www.panda.tv/all';var app = express();app.set('port', process.env.PORT || 3000);function filterVideos(html) {    var $ = cheerio.load(html);    var videos = $('#later-play-list').children('li');    var videosData = [];    videos.each(function(item) {        var video = $(this);        var videoTitle = video.find('.video-title').text();        var videoInfo = video.find('.video-info');        var videoData = {            videoTitle:videoTitle,            videoInfo: []        }        videoInfo.each(function(item) {            var videoNickname = $(this).find('.video-nickname').text();                        var videoId = $(this).find('.video-number').text();            var videoClass = $(this).find('.video-cate').text();            videoData.videoInfo.push({                name:videoNickname,                id:videoId,                cate:videoClass            })        })        videosData.push(videoData);    })    return videosData;}function printVideoInfo(videosData) {    var data = [];    videosData.forEach(function(item) {        var videoTitle = item.videoTitle;        item.videoInfo.forEach(function(videoInfo) {            data.push(videoTitle + '--------' + videoInfo.name + ' [' + '人数:' + videoInfo.id + ' ' + '类型:' + videoInfo.cate + ']');            // console.log(videoTitle + '--------' + videoInfo.name);            // console.log('人数:' + videoInfo.id + '  ' + '类型:' +videoInfo.cate + '\n');        })    })    return data;}app.get('/', function(req,res,next) {    superagent        .get(url)        .end(function(err,sres) {            if (err) {                 return next(err);            } else {                                var videosData = filterVideos(sres.text);                var data = printVideoInfo(videosData);                var result = '';                for (var i = 0 ; i < data.length ; i++ ) {                    result += '<p>' + (i+1) + ':' + data[i] + '</p>' ;                };                res.send(result);            }                   })})app.listen(app.get('port'));

filterVideos函数是将请求页面的html内容进行过滤,筛选我所需要的信息。这些数据的结构如图:
这里写图片描述
printVideoInfo函数是将我的数据结构转化为一定的格式,使之更清晰明了地显示在页面上。
最后通过一个路由把数据发送到页面上。有一个小问题是,通过printVideoInfo函数得到的data是一个数组,如何把数组的每个元素逐行打印到页面上呢?我首先想当然地通过一个for循环,每次send一个元素,结果如何?页面只显示了数组的第一个元素,并且命令行上报了一个cant set headers after they are send.虽然不太懂原理,大概就是不能重复send的意思吧…(逃)。之后便有了这个方法,把每个元素包装上< p>,通过一个循环把所有的< p>语句连接到一个字符串result中,再进行res.send(result)就成功了。结果如下图(不同时间点的直播信息不同):
这里写图片描述
到这里一个简易的爬虫程序就完成了。虽然这个程序没有很复杂的算法,也只取到了首页的直播数据,但也是一个nodejs小白的第一个爬虫程序,各位大神非喜勿喷!

1 0
原创粉丝点击