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 相关文章推荐
Gird事件机制初级读本
Mar 10 Javascript
javascript实现div浮动在网页最顶上并带关闭按钮效果实例
Aug 13 Javascript
Js实现动态添加删除Table行示例
Apr 14 Javascript
js 判断图片是否加载完以及实现图片的预下载
Aug 14 Javascript
5个数组Array方法: indexOf、filter、forEach、map、reduce使用实例
Jan 29 Javascript
JQuery实现防止退格键返回的方法
Feb 12 Javascript
jQuery判断指定id的对象是否存在的方法
May 22 Javascript
javascript中获取元素标签中间的内容的实现方法
Oct 08 Javascript
怎样判断jQuery当前元素是隐藏还是显示
Nov 23 Javascript
canvas简单快速的实现知乎登录页背景效果
May 08 Javascript
jQuery实现选中行变色效果(实例讲解)
Jul 06 jQuery
Ajax常用封装库——Axios的使用
May 08 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
德生PL330测评
2021/03/02 无线电
在字符串指定位置插入一段字符串的php代码
2010/02/16 PHP
PHP合并两个数组的两种方式的异同
2012/09/14 PHP
PHP实现字母数字混合验证码功能
2019/07/11 PHP
静态的动态续篇之来点XML
2006/12/23 Javascript
基于Jquery的回车成tab焦点切换效果代码(Enter To Tab )
2010/11/14 Javascript
jquery表单验证插件(jquery.validate.js)的3种使用方式
2015/03/28 Javascript
浅析Nodejs npm常用命令
2016/06/14 NodeJs
JavaScript数组去重由慢到快由繁到简(优化篇)
2016/08/26 Javascript
Vue.js使用v-show和v-if的注意事项
2016/12/13 Javascript
轻松理解JavaScript闭包
2017/03/14 Javascript
Nodejs+angularjs结合multiparty实现多图片上传的示例代码
2017/09/29 NodeJs
基于IView中on-change属性的使用详解
2018/03/15 Javascript
Mint UI实现A-Z字母排序的城市选择列表
2018/12/28 Javascript
Vue循环遍历选项赋值到对应控件的实现方法
2020/06/22 Javascript
[01:45]亚洲邀请赛互动指南虚拟物品介绍
2015/01/30 DOTA
pymssql数据库操作MSSQL2005实例分析
2015/05/25 Python
使用httplib模块来制作Python下HTTP客户端的方法
2015/06/19 Python
Python实现一个简单的验证码程序
2017/11/03 Python
在Python中输入一个以空格为间隔的数组方法
2018/11/13 Python
python日志logging模块使用方法分析
2019/05/23 Python
python实现证件照换底功能
2019/08/20 Python
python如何将图片转换素描画
2020/09/08 Python
可以在一个PHP文件里面include另外一个PHP文件两次吗
2015/05/22 面试题
将一个文本文件的内容按倒序打印出来
2015/01/05 面试题
工商技校毕业生自荐信
2013/11/15 职场文书
运动会广播稿300字
2014/01/10 职场文书
护士岗位求职应聘自荐书范文
2014/02/12 职场文书
幼儿园教师工作感言
2014/02/15 职场文书
陈欧的广告词
2014/03/18 职场文书
《画杨桃》教学反思
2014/04/13 职场文书
大学生村官座谈会发言材料
2014/05/25 职场文书
汽车转让协议书范本
2014/12/07 职场文书
2014年小学辅导员工作总结
2014/12/23 职场文书
优秀护士事迹材料
2014/12/25 职场文书
农民工工资承诺书大全
2015/05/04 职场文书