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 相关文章推荐
六款帮助你实现惊艳视差滚动效果的jQuery插件
Sep 14 Javascript
点击隐藏页面左栏或右栏实现js代码
Apr 01 Javascript
常用的几段javascript代码分享
Mar 25 Javascript
JQuery插件iScroll实现下拉刷新,滚动翻页特效
Jun 22 Javascript
用console.table()调试javascript
Sep 04 Javascript
JS数组去掉重复数据只保留一条的实现代码
Aug 11 Javascript
angular分页指令操作
Jan 09 Javascript
Bootstrap标签页(Tab)插件使用方法
Mar 21 Javascript
Easyui ueditor 整合解决不能编辑的问题(推荐)
Jun 25 Javascript
js canvas实现适用于移动端的百分比仪表盘dashboard
Jul 18 Javascript
详解js中的几种常用设计模式
Jul 16 Javascript
解决VUE项目使用Element-ui 下拉组件的验证失效问题
Nov 07 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
substr()函数中文版
2006/10/09 PHP
PHP中一个控制字符串输出的函数
2006/10/09 PHP
php仿discuz分页效果代码
2008/10/02 PHP
php截取utf-8中文字符串乱码的解决方法
2010/03/29 PHP
PHP通过header实现文本文件下载的代码
2010/08/08 PHP
thinkPHP使用pclzip打包备份mysql数据库的方法
2016/04/30 PHP
PHP Swoole异步读取、写入文件操作示例
2019/10/24 PHP
UserData用法总结 lanyu出品
2010/07/01 Javascript
javascript控制在光标位置插入文字适合表情的插入
2014/06/09 Javascript
Javascript通过overflow控制列表闭合与展开的方法
2015/05/15 Javascript
深入理解JavaScript函数参数(推荐)
2016/07/26 Javascript
js实现按钮控制带有停顿效果的图片滚动
2016/08/30 Javascript
简单实现js菜单栏切换效果
2017/03/04 Javascript
Vue.js 表单控件操作小结
2018/03/29 Javascript
webpack4 CSS Tree Shaking的使用
2018/09/03 Javascript
实例讲解JavaScript 计时事件
2020/07/04 Javascript
详解vue修改elementUI的分页组件视图没更新问题
2020/11/13 Javascript
js实现扫雷源代码
2020/11/27 Javascript
wxpython 最小化到托盘与欢迎图片的实现方法
2014/06/09 Python
PyMongo安装使用笔记
2015/04/27 Python
python3 selenium 切换窗口的几种方法小结
2018/05/21 Python
python 哈希表实现简单python字典代码实例
2019/09/27 Python
python3 xpath和requests应用详解
2020/03/06 Python
CSS3 清除浮动的方法示例
2018/06/01 HTML / CSS
美国顶级水上运动专业店:Marine Products
2018/04/15 全球购物
英国现代家具和装饰网站:PN Home
2018/08/16 全球购物
乌克兰在线药房:Аптека24
2019/10/30 全球购物
String和StringBuffer的区别
2015/08/13 面试题
构造方法和其他方法的区别
2016/04/26 面试题
门卫岗位安全职责
2013/12/13 职场文书
迎元旦广播稿
2014/02/22 职场文书
教育英语专业毕业生的求职信
2014/03/13 职场文书
运动会宣传口号
2014/06/09 职场文书
爱牙日宣传活动总结
2015/02/05 职场文书
2019年暑期法院实习报告
2019/12/18 职场文书
python实现自定义日志的具体方法
2021/05/28 Python