这个教程十分适合初学 Node.js 的初学者看(由于我也是一只初学的菜鸟~)javascript
在这里,我就默认你们都已经在本身的电脑上搭建好 node.js,我就再也不多讲了,若是你是第一次接触 Node.js 那么先请到能够到Node.js 中文网(英文) 上看看,里面有完整的安装教程。css
想直接看源码的能够直接移步到 github imooc-video-download。html
说到下载视频,首先咱们要先有个大概思路:java
发送请求—>获取视频下载地址->发送下载请求下载视频—>把视频文件写入本地node
由于须要发起请求,在这里我用到 superagent 是个 http 方面的库,能够发起 get 或 post 请求。jquery
由于要解析网页,在这里我使用 cheerio 咱们能够把它当作一个 Node.js 版的 jQuery,用来从网页中以 css selector 取数据,使用方式跟 jquery 同样的。git
写文件的话就用 Node.js 自带的 fs
文件模块。github
既然思路有了,那就开始上代码吧~web
$ cd ~/Documents/NodeJs $ mkdir immoc-video-download $ cd immoc-video-download $ npm init
ps:接下来会让你填不少信息,所有直接回车就能够(也能够认真写写),最后须要输入 yes
加回车结束。ajax
我解释一下一步,npm init
是初始化一个项目,互动式帮咱们生成一个最简单的 package.json 文件,而这个 package.json 文件包含咱们项目名,做者,项目依赖等等信息。
$ npm install superagent cheerio --save
--save
是个可选参数,加了它以后会自动帮咱们把上面安装的两个模块自动写入到 package.json 里面。
$ touch app.js #新建一个名为 app.js 的文件
到这一步,这个爬虫项目所须要的环境和依赖的都已经准备好了。
用编辑器打开 app.js 这个文件,在里面输入
var superagent = require('superagent'); var cheerio = require('cheerio'); var fs = require('fs');
var superagent = require('superagent'); var cheerio = require('cheerio'); var fs = require('fs'); var url = '慕课网课程' var savePath = '保存文件路径' superagent .get(url) .end(function(err, res) { }) // 获取视频 url var getVideoUrl = function() { } // 下载视频 var downloadVideo = function() { }
基本框架已经没问题了,不过里面啥都没,怎么办?
别慌,爬虫嘛,固然是在网页上爬数据。
先上图!
http://www.imooc.com/learn/441
看这里!!
咱们来看看慕课网的网站源码,发现没?每一个视频都有一个视频的id,再来看看课程的 URL 课程也有一个课程 ID 。
咱们都知道这个网站的视频是须要登陆以后才能够看观看的,这就表明咱们在请求的时候要在 headers 里作些手脚,把 cookies 放进去
先上图!
看完这些咱们应该有个大概清晰的思路了吧,废话很少说,完善代码。
var headers = { "Cache-Control": "max-age=0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Referer": "http://www.imooc.com/", "Accept-Encoding": "gzip, deflate, sdch", "Accept-Language": "zh-CN,zh;q=0.8", "Cookie": cookies // 在外面定义一个 cookies 变量存放本身的 cookies };
这里就是直接把上一个截图里的 request headers 里面的全部数据都 copy 进去。
superagent
.get('www.imooc.com/learn/' + courseId) // 在外面设置一个 courseId 的参数 .set(headers) .end(function(err, res) { // res.text 经过请求获取的 html 页面 var $ = cheerio.load(res.text); // 获取课程的名称 $('.course-infos .hd').find('h2').each(function(item) { courseTitle = $(this).text(); }) // .chapter 是包含全部 video 的容器,这是 jquery 语法,为了获取全部的视频 id 和 filename $('.chapter').each(function(item) { var videos = $(this).find('.video').children('li') videos.each(function(item) { var video = $(this).find('a') var filename = video.text().replace(/(^\\\\\\\\s+)|(\\\\\\\\s+$)/g,""); var id = video.attr('href').split('video/')[1] // 视频 id 和 视频文件名字 console.log(id, filename); }) }) })
上面那段代码帮咱们获取了每一个视频的 id 和 它的文件名,那么接下来咱们只须要获取它的视频下载地址就 ok。
这时候咱们还获得视频播放页面去抓取一下网站播放视频请求的地址:
在过滤器中输入视频的格式 mp4 过滤一下(找不到的话试试 flv 之类的),看到出现了咱们想要的 mp4 文件,是否是特别激动!!
看一下头文件,什么鬼?!这串东西什么??能够确定,这不是咱们想要的。
咱们试试输入视频 id 做过滤条件
点那个 preview(response显示的东西太长很难截图) 看看它给咱们返回什么:
看!出来了。
咱们能够看到这是 ajax 请求的一个地址,不要紧,既然给咱们找到了,那就拼接一下就 ok 了。
上代码!
var getVideoUrl = function(id, callback) { superagent.get('http://www.imooc.com/course/ajaxmediainfo/?mid=' + id + '&mode=flash') .end(function(err, res) { var url = JSON.parse(res.text); if(url.result == 0) { url = url.data.result.mpath[0]; callback(url); } }) }
有了上面的 url 接下来咱们的功夫就简单多了。
直接上代码:
var downloadVideo = function(url, filename, callback) { // 去掉文件名后面的时间 // 2-1 登陆动画-冒泡 (10:53) —> 2-1 登陆动画-冒泡.mp4 filename = filename.replace(/\\\\\\\\(.*\\\\\\\\)/,'') + '.mp4'; // 建立一个以课程名字命名的目录存放视频 var dirPath = savePath + courseTitle + '/' if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath); } console.log('开始下载第' + courseTotalCount + '个视频' + filename + ' 地址: ' + url); var writeStream = fs.createWriteStream(dirPath + filename); writeStream.on('close', function() { callback(filename); }) var req = superagent.get(url) req.pipe(writeStream); }
看到这里是否是特别兴奋!!!
别急,接着咱们再加入这行代码。
var courseId = process.argv.splice(2, 1);
ok!大功告成!
咱们下载视频的时候只须要在终端执行下面这行命令就能够了。
$ node app courseId # 你想下载的视频 id
这个项目已上传到 github imooc-video-download