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代码
Dec 04 Javascript
asp.net网站开发中用jquery实现滚动浏览器滚动条加载数据(类似于腾讯微博)
Mar 14 Javascript
自定义的一个简单时尚js下拉选择框
Nov 20 Javascript
Node.js中HTTP模块与事件模块详解
Nov 14 Javascript
javascript禁止访客复制网页内容的实现代码
Aug 05 Javascript
ajax分页效果(bootstrap模态框)
Jan 23 Javascript
javascript 判断一个对象为数组的方法
May 03 Javascript
JavaScript实现简单的双色球(实例讲解)
Jul 31 Javascript
jQuery中ajax请求后台返回json数据并渲染HTML的方法
Aug 08 jQuery
vue项目从node8.x升级到12.x后的问题解决
Oct 25 Javascript
JavaScript中的this原理及6种常见使用场景详解
Feb 14 Javascript
JavaScript构造函数原理及实现流程解析
Nov 19 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中{}大括号是什么意思
2013/12/01 PHP
php中$_POST与php://input的区别实例分析
2015/01/07 PHP
php使用explode()函数将字符串拆分成数组的方法
2015/02/17 PHP
Laravel 5.4重新登录实现跳转到登录前页面的原理和方法
2017/07/13 PHP
Javascript里使用Dom操作Xml
2006/09/20 Javascript
javascript面向对象之Javascript 继承
2010/05/04 Javascript
总结Javascript中数组各种去重的方法
2016/10/04 Javascript
js节流防抖应用场景,以及在vue中节流防抖的具体实现操作
2020/09/21 Javascript
[03:11]2014DOTA2国际邀请赛-VG掉入败者组 独家专访357
2014/07/19 DOTA
[42:39]老党炸弹人试玩视频
2014/09/03 DOTA
关于Python面向对象编程的知识点总结
2017/02/14 Python
python中requests使用代理proxies方法介绍
2017/10/25 Python
13个最常用的Python深度学习库介绍
2017/10/28 Python
Python DataFrame 设置输出不显示index(索引)值的方法
2018/06/07 Python
python3.6.3转化为win-exe文件发布的方法
2018/10/31 Python
pyqt5 lineEdit设置密码隐藏,删除lineEdit已输入的内容等属性方法
2019/06/24 Python
利用4行Python代码监测每一行程序的运行时间和空间消耗
2020/04/22 Python
Jupyter notebook如何修改平台字体
2020/05/13 Python
django美化后台django-suit的安装配置操作
2020/07/12 Python
pycharm实现猜数游戏
2020/12/07 Python
Python的信号库Blinker用法详解
2020/12/31 Python
css3编写浏览器背景渐变背景色的方法
2018/03/05 HTML / CSS
欧舒丹英国官网:购买欧舒丹护手霜等明星产品
2017/01/17 全球购物
鞋子女王塔玛拉·梅隆同名奢侈品牌:Tamara Mellon
2017/11/22 全球购物
Crocs欧洲官网:Crocs Europe
2020/01/14 全球购物
DJI全球:DJI Global
2021/03/15 全球购物
英国最大的在线照明商店:Litecraft
2020/08/31 全球购物
师范生实习的个人自我鉴定
2013/10/20 职场文书
九年级政治教学反思
2014/02/06 职场文书
《母亲的恩情》教学反思
2014/02/13 职场文书
《泉水》教学反思
2014/04/11 职场文书
幼儿园欢迎词范文
2015/01/26 职场文书
大学生团支书竞选稿
2015/11/21 职场文书
我的中国梦心得体会范文
2016/01/05 职场文书
Python机器学习之KNN近邻算法
2021/05/14 Python
三星 3nm 芯片将于第二季度开始量产
2022/04/29 数码科技