Node批量爬取头条视频并保存方法


Posted in Javascript onSeptember 20, 2018

简介

一般批量爬取视频或者图片的套路是,使用爬虫获得文件链接集合,然后通过 writeFile 等方法逐个保存文件。然而,头条的视频,在需要爬取的 html 文件(服务端渲染输出)中,无法捕捉视频链接。视频链接是页面在客户端渲染时,通过某些 js 文件内的算法或者解密方法,根据视频的已知 key 或者 hash 值,动态计算出来并添加到 video 标签的。这也是网站的一种反爬措施。

我们在浏览这些页面时,通过审核元素,可以看到计算后的文件地址。然而在批量下载时,逐个手动的获取视频链接显然不可取。开心的是,puppeteer 提供了模拟访问 Chrome 的功能,使我们可以爬取经过浏览器渲染出来的最终页面。

项目启动

命令

npm i
npm start

Notice: 安装 puppeteer 的过程稍慢,耐心等待。

配置文件

// 配置相关
module.exports = {
 originPath: 'https://www.ixigua.com', // 页面请求地址
 savePath: 'D:/videoZZ' // 存放路径
}

技术点

puppeteer

官方API

puppeteer 提供一个高级 API 来控制 Chrome 或者 Chromium。

puppeteer 主要作用:

利用网页生成 PDF、图片

爬取SPA应用,并生成预渲染内容(即“SSR” 服务端渲染)

可以从网站抓取内容

自动化表单提交、UI测试、键盘输入等

使用到的 API:

puppeteer.launch() 启动浏览器实例

browser.newPage() 创建一个新页面

page.goto() 进入指定网页

page.screenshot() 截图

page.waitFor() 页面等待,可以是时间、某个元素、某个函数

page.$eval() 获取一个指定元素,相当于 document.querySelector

page.$$eval() 获取某类元素,相当于 document.querySelectorAll

page.$('#id .className') 获取文档中的某个元素,操作类似jQuery

代码示例

const puppeteer = require('puppeteer');
 
(async () => {
 const browser = await puppeteer.launch();
 const page = await browser.newPage();
 await page.goto('https://example.com');
 await page.screenshot({path: 'example.png'});
 
 await browser.close();
})();

视频文件下载方法

下载视频主方法

const downloadVideo = async video => {
 // 判断视频文件是否已经下载
 if (!fs.existsSync(`${config.savePath}/${video.title}.mp4`)) {
 await getVideoData(video.src, 'binary').then(fileData => {
  console.log('下载视频中:', video.title)
  savefileToPath(video.title, fileData).then(res =>
  console.log(`${res}: ${video.title}`)
  )
 })
 } else {
 console.log(`视频文件已存在:${video.title}`)
 }
}

获取视频数据

getVideoData (url, encoding) {
 return new Promise((resolve, reject) => {
 let req = http.get(url, function (res) {
  let result = ''
  encoding && res.setEncoding(encoding)
  res.on('data', function (d) {
  result += d
  })
  res.on('end', function () {
  resolve(result)
  })
  res.on('error', function (e) {
  reject(e)
  })
 })
 req.end()
 })
}

将视频数据保存到本地

savefileToPath (fileName, fileData) {
 let fileFullName = `${config.savePath}/${fileName}.mp4`
 return new Promise((resolve, reject) => {
 fs.writeFile(fileFullName, fileData, 'binary', function (err) {
  if (err) {
  console.log('savefileToPath error:', err)
  }
  resolve('已下载')
 })
 })
}

目标网站:西瓜视频

项目功能:下载头条号【维辰财经】下的最新20个视频

项目地址:Github 地址

Javascript 相关文章推荐
js弹窗代码 可以指定弹出间隔
Jul 03 Javascript
JavaScript 匿名函数(anonymous function)与闭包(closure)
Oct 04 Javascript
自己实现ajax封装示例分享
Apr 01 Javascript
bootstrap-wysiwyg结合ajax实现图片上传实时刷新功能
May 27 Javascript
JS控制div跳转到指定的位置的几种解决方案总结
Nov 05 Javascript
js+css3实现旋转效果
Jan 20 Javascript
Bootstrap表格制作代码
Mar 17 Javascript
AngularJS 异步解决实现方法
Jun 12 Javascript
使用Node.js搭建静态资源服务详细教程
Aug 02 Javascript
Vue下滚动到页面底部无限加载数据的示例代码
Apr 22 Javascript
一份超级详细的Vue-cli3.0使用教程【推荐】
Nov 15 Javascript
使用React代码动态生成栅格布局的方法
May 24 Javascript
vue 本地环境跨域请求proxyTable的方法
Sep 19 #Javascript
vue 优化CDN加速的方法示例
Sep 19 #Javascript
Vue前后端不同端口的实现方法
Sep 19 #Javascript
vue-cli 3.x 修改dist路径的方法
Sep 19 #Javascript
浅谈React之状态(State)
Sep 19 #Javascript
jQuery使用each遍历循环的方法
Sep 19 #jQuery
vue新vue-cli3环境配置和模拟json数据的实例
Sep 19 #Javascript
You might like
又十个超级有用的PHP代码片段
2015/09/24 PHP
PHP编写RESTful接口
2016/02/23 PHP
THinkPHP获取客户端IP与IP地址查询的方法
2016/11/14 PHP
Laravel网站打开速度优化的方法汇总
2017/07/16 PHP
PHP大文件分割上传 PHP分片上传
2017/08/28 PHP
PHP实现PDO操作mysql存储过程示例
2019/02/13 PHP
JS日期和时间选择控件升级版(自写)
2013/08/02 Javascript
将中国标准时间转换成标准格式的代码
2014/03/20 Javascript
JSON遍历方式实例总结
2015/12/07 Javascript
JQuery Dialog对话框 不能通过Esc关闭的原因分析及解决办法
2017/01/18 Javascript
jQuery Validate 校验多个相同name的方法
2017/05/18 jQuery
node.js中express-session配置项详解
2017/05/31 Javascript
zTree树形插件异步加载方法详解
2017/06/14 Javascript
解决Vue axios post请求,后台获取不到数据的问题方法
2018/08/11 Javascript
使用 Github Actions 自动部署 Angular 应用到 Github Pages的方法
2020/07/20 Javascript
django通过ajax发起请求返回JSON格式数据的方法
2015/06/04 Python
python下读取公私钥做加解密实例详解
2017/03/29 Python
Python实现购物车程序
2018/04/16 Python
解决jupyter运行pyqt代码内核重启的问题
2020/04/16 Python
html5通过canvas实现刮刮卡效果示例分享
2014/01/27 HTML / CSS
世界上最大的在线旅行社新加坡网站:Expedia新加坡
2016/08/25 全球购物
美国二手奢侈品寄售网站:TheRealReal
2016/10/29 全球购物
UML设计模式笔试题
2014/06/07 面试题
总裁岗位职责
2013/12/04 职场文书
兼职业务员岗位职责
2014/01/01 职场文书
医院辞职信范文
2014/01/17 职场文书
办公室秘书自我鉴定
2014/01/18 职场文书
高中英语教学反思
2014/02/04 职场文书
大学生活动策划方案
2014/02/10 职场文书
出售房屋协议书范本
2014/10/06 职场文书
交心谈心活动总结
2015/05/11 职场文书
董事长开业致辞
2015/07/29 职场文书
深入浅析React中diff算法
2021/05/19 Javascript
一文搞懂python异常处理、模块与包
2021/06/26 Python
Win11软件图标固定到任务栏
2022/04/19 数码科技
JS实现简单的九宫格抽奖
2022/06/28 Javascript