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 相关文章推荐
JavaScript中Math对象使用说明
Jan 16 Javascript
js 屏蔽鼠标右键脚本附破解方法
Dec 03 Javascript
JQuery 选择器、过滤器介绍
Feb 14 Javascript
用C/C++来实现 Node.js 的模块(二)
Sep 24 Javascript
JavaScript定时器和优化的取消定时器方法
Jul 03 Javascript
学习使用bootstrap基本控件(table、form、button)
Apr 12 Javascript
js重写方法的简单实现
Jul 10 Javascript
javascript实现循环广告条效果
Dec 12 Javascript
highCharts提示框中显示当前时间的方法
Jan 18 Javascript
Vue 组件参数校验与非props特性的方法
Feb 12 Javascript
Vue + Elementui实现多标签页共存的方法
Jun 12 Javascript
10种JavaScript最常见的错误(小结)
Jun 21 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
CPU步进是什么意思?i3-9100F B0步进和U0步进区别知识科普
2020/03/17 数码科技
使用PHP curl模拟浏览器抓取网站信息
2013/10/28 PHP
php删除指定目录的方法
2015/04/03 PHP
老生常谈php中传统验证与thinkphp框架(必看篇)
2017/06/10 PHP
PHP折半(二分)查找算法实例分析
2018/05/12 PHP
php项目中类的自动加载实例讲解
2019/09/12 PHP
学习YUI.Ext基础第一天
2007/03/10 Javascript
编写兼容IE和FireFox的脚本
2009/05/18 Javascript
javawscript 三级菜单的实现原理
2009/07/01 Javascript
学习javascript面向对象 理解javascript对象
2016/01/04 Javascript
GitHub上一些实用的JavaScript的文件压缩解压缩库推荐
2016/03/13 Javascript
一分钟理解js闭包
2016/05/04 Javascript
深入理解jquery自定义动画animate()
2016/05/24 Javascript
URL的参数中有加号传值变为空格的问题(URL特殊字符)
2016/11/04 Javascript
bootstrap中selectpicker下拉框使用方法实例
2018/03/22 Javascript
openlayers 3实现车辆轨迹回放
2020/09/24 Javascript
Array.filter中如何正确使用Async
2020/11/04 Javascript
python 异常处理总结
2016/10/18 Python
python开发准备工作之配置虚拟环境(非常重要)
2019/02/11 Python
Python 实现文件打包、上传与校验的方法
2019/02/13 Python
python多线程http压力测试脚本
2019/06/25 Python
如何使用Python实现斐波那契数列
2019/07/02 Python
实例详解Python装饰器与闭包
2019/07/29 Python
Python描述数据结构学习之哈夫曼树篇
2020/09/07 Python
python中slice参数过长的处理方法及实例
2020/12/15 Python
详解python使用金山词霸的翻译功能(调试工具断点的使用)
2021/01/07 Python
python中scipy.stats产生随机数实例讲解
2021/02/19 Python
浅谈CSS3特性查询(Feature Query: @supports)功能简介
2017/07/31 HTML / CSS
美国新兴城市生活方式零售商:VILLA
2017/12/06 全球购物
澳大利亚领先的在线礼品网站:Gifts Australia
2020/08/15 全球购物
金属材料工程毕业生个人的自我评价
2013/11/28 职场文书
科长竞争上岗演讲稿
2014/05/12 职场文书
总结会主持词
2015/07/02 职场文书
如何把新闻人物写得立体、鲜活?
2019/08/14 职场文书
spring注解 @PropertySource配置数据源全流程
2022/03/25 Java/Android
浅谈为什么我的 z-index 又不生效了
2022/07/15 HTML / CSS