這個教程十分適合初學 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