教你一步一步用 Node.js 制作慕课网视频爬虫
转自:http://www.jianshu.com/p/d7631fc695af
开始
这个教程十分适合初学 Node.js 的初学者看(因为我也是一只初学的菜鸟~)
在这里,我就默认大家都已经在自己的电脑上搭建好 node.js,我就不再多讲了,如果你是第一次接触 Node.js 那么先请到可以到Node.js 中文网(英文) 上看看,里面有完整的安装教程。
想直接看源码的可以直接移步到 github imooc-video-download。
第一步
说到下载视频,首先我们要先有个大概思路:
发送请求—>获取视频下载地址->发送下载请求下载视频—>把视频文件写入本地
因为需要发起请求,在这里我用到 superagent是个 http 方面的库,可以发起 get 或 post 请求。
因为要解析网页,在这里我使用 cheerio我们可以把它当做一个 Node.js 版的 jQuery,用来从网页中以 css selector 取数据,使用方式跟 jquery 一样的。
写文件的话就用 Node.js 自带的
fs文件模块。
第二步
既然思路有了,那就开始上代码吧~
新建一个项目:
$ cd ~/Documents/NodeJs
$ mkdir immoc-video-download
$ cd immoc-video-download
$ npm init
ps:接下来会让你填很多信息,全部直接回车就可以(也可以认真写写),最后需要输入 yes 加回车结束。
我解释一下一步,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 放进去
请求头分析
先上图!
看完这些我们应该有个大概清晰的思路了吧,废话不多说,完善代码。
解析视频 id 和 filename
看看核心代码
先写一个请求头:
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 进去。
解析 html:
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
原文链接:http://www.jianshu.com/p/d7631fc695af
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
教你一步一步用 Node.js 制作慕课网视频爬虫的更多相关文章
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 错误处理
沪江CCtalk视频地址:https://www.cctalk.com/v/15114923887518 处理错误请求 爱能遮掩一切过错. 当我们在访问一个站点的时候,如果访问的地址不存在(404), ...
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 代码分层
视频地址:https://www.cctalk.com/v/15114923889408 文章 在前面几节中,我们已经实现了项目中的几个常见操作:启动服务器.路由中间件.Get 和 Post 形式的请 ...
- PHP, Python, Node.js 哪个比较适合写爬虫?
PHP, Python, Node.js 哪个比较适合写爬虫? 1.对页面的解析能力2.对数据库的操作能力(mysql)3.爬取效率4.代码量推荐语言时说明所需类库或者框架,谢谢.比如:python+ ...
- 基于node.js制作爬虫教程
前言:最近想学习node.js,突然在网上看到基于node的爬虫制作教程,所以简单学习了一下,把这篇文章分享给同样初学node.js的朋友. 目标:爬取 http://tweixin.yueyishu ...
- node.js 开发简易的小爬虫
node.js 开发简易的小爬虫 最近公司开发一款医药类的软件,所以需要一些药品的基础数据,所以本人就用node.js写一个简易的小爬虫,并写记录这个Demo以供大家参考. 一.开发前的准备: 1, ...
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 记录日志
沪江CCtalk视频地址:https://www.cctalk.com/v/15114923883523 log 日志中间件 最困难的事情就是认识自己. 在一个真实的项目中,开发只是整个投入的一小部分 ...
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 解析JSON
视频地址:https://www.cctalk.com/v/15114923886141 JSON 数据 我颠倒了整个世界,只为摆正你的倒影. 前面的文章中,我们已经完成了项目中常见的问题,比如 路由 ...
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 处理静态资源
视频地址:https://www.cctalk.com/v/15114923882788 处理静态资源 无非花开花落,静静. 指定静态资源目录 这里我们使用第三方中间件: koa-static 安装并 ...
- iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 视图Nunjucks
视频地址:https://www.cctalk.com/v/15114923888328 视图 Nunjucks 彩虹是上帝和人类立的约,上帝不会再用洪水灭人. 客户端和服务端之间相互通信,传递的数据 ...
随机推荐
- (一)MySQL登录与退出
mysql登陆: win+r输入cmd按enter进入命令行界面: > mysql -uroot -p -P3306 -h127.0.0.1 > 输入密码后按回车 mysql退出: mys ...
- MySQL 字符串拼接
MySQL 字符串拼接 在Mysql 数据库中存在两种字符串连接操作.具体操作如下 1. CONCAT(string1,string2,…) 说明 : string1,string2代表字符串,c ...
- 01: 重写Django admin
目录: 1.1 重写Django admin项目各文件作用# 1.2 重写Django admin用户认证 1.3 将要显示的表注册到我们自己的kind_admin.py中 1.4 项目首页:显示注册 ...
- ELK之kibana6.5
ELK之安装kibana6.5,这里采用rpm安装: https://www.elastic.co/guide/en/kibana/current/rpm.html # wget https://ar ...
- vijos & codevs 能量项链 - 动态规划
描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定等于 ...
- 使用Oracle执行计划分析SQL性能
执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述.即就是对一个查询任务,做出一份怎样去完成任务的详细方案. 如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的 ...
- POJ 1740 A New Stone Game(博弈)题解
题意:有n个石子堆,每一个都可以轮流做如下操作:选一个石堆,移除至少1个石子,然后可以把这堆石子随便拿几次,随便放到任意的其他石子数不为0的石子堆,也可以不拿.不能操作败. 思路:我们先来证明,如果某 ...
- 项目梳理5——修改已生成.nuspec文件
xxxx.nuspec格式如下 <?xml version="1.0"?> <package > <metadata> <id>$i ...
- 分布式事务之——tcc-transaction分布式TCC型事务框架搭建与实战案例(基于Dubbo/Dubbox)
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/73731363 一.背景 有一定分布式开发经验的朋友都知道,产品/项目/系统最初为了 ...
- POJ 1509 Glass Beads---最小表示法
题意: T组数据,每组数据给出一个字符串,求这个字符串的最小表示发(只要求输出起始位置坐标) SAM入门题(检测板子是否正确). 将字符串S加倍丢进SAM中,然后走字符串长度次,每次贪心的沿最小的边走 ...