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 12 Javascript
JQuery 1.6发布 性能提升,同时包含大量破坏性变更
May 10 Javascript
javascript bom是什么及bom和dom的区别
Nov 26 Javascript
js仿手机页面文件下拉刷新效果
Oct 14 Javascript
AngularJS中一般函数参数传递用法分析
Nov 22 Javascript
jquery实现简单的瀑布流布局
Dec 11 Javascript
ajax 提交数据到后台jsp页面及页面跳转问题
Jan 19 Javascript
在vue中获取token,并将token写进header的方法
Sep 26 Javascript
angularjs使用div模拟textarea文本框的方法
Oct 02 Javascript
关于JS模块化的知识点分享
Oct 16 Javascript
js实现小星星游戏
Mar 23 Javascript
vue基于Teleport实现Modal组件
May 31 Vue.js
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
ThinkPHP中__initialize()和类的构造函数__construct()用法分析
2014/11/29 PHP
PHP使Laravel为JSON REST API返回自定义错误的问题
2018/10/16 PHP
JavaScript XML实现两级级联下拉列表
2008/11/10 Javascript
jquery select动态加载选择(兼容各种浏览器)
2013/02/01 Javascript
iScroll中事件点击触发两次解决方案
2015/03/11 Javascript
javascript实现数组内值索引随机化及创建随机数组的方法
2015/08/10 Javascript
详解Bootstrap glyphicons字体图标
2016/01/04 Javascript
javascript实现移动端上的触屏拖拽功能
2016/03/04 Javascript
vue-router单页面路由
2017/06/17 Javascript
js插件实现图片滑动验证码
2020/09/29 Javascript
Vue官方推荐AJAX组件axios.js使用方法详解与API
2018/10/09 Javascript
vue使用keep-alive保持滚动条位置的实现方法
2019/04/09 Javascript
使用JS location实现搜索框历史记录功能
2019/12/23 Javascript
Python 时间操作例子和时间格式化参数小结
2014/04/24 Python
Python检测网站链接是否已存在
2016/04/07 Python
速记Python布尔值
2017/11/09 Python
Python File readlines() 使用方法
2018/03/19 Python
pandas数据清洗,排序,索引设置,数据选取方法
2018/05/18 Python
对Pandas MultiIndex(多重索引)详解
2018/11/16 Python
Python 最大概率法进行汉语切分的方法
2018/12/14 Python
关于win10在tensorflow的安装及在pycharm中运行步骤详解
2020/03/16 Python
Python趣味入门教程之循环语句while
2020/08/26 Python
如何利用Python matplotlib绘制雷达图
2020/12/21 Python
利用CSS3实现文字折纸效果实例代码
2018/07/10 HTML / CSS
Rag & Bone官网:瑞格布恩高级成衣
2018/04/19 全球购物
TIME时代杂志台湾总代理:台时亚洲
2018/10/22 全球购物
DeinDesign德国:设计自己的手机壳
2019/12/14 全球购物
秋季开学典礼主持词
2014/03/19 职场文书
社区活动策划方案
2014/08/21 职场文书
2014年机关工会工作总结
2014/12/19 职场文书
舞出我人生观后感
2015/06/16 职场文书
Vue-Element-Admin集成自己的接口实现登录跳转
2021/06/23 Vue.js
bat批处理之字符串操作的实现
2022/03/16 Python
Mysql数据库事务的脏读幻读及不可重复读详解
2022/05/30 MySQL
Python使用pyecharts控件绘制图表
2022/06/05 Python
怎么禁用Win11输入法 最新Win11输入法关闭教程
2022/08/05 数码科技