利用 Node.JS,request 包 定时爬去 网站视频 ts 接口, 大概有 1771 个文件.
首先, 获取到网站的 ts 视频分段配置文件, 获取到后, 放入本地文件, 方便下次使用.
然后, 定时调用下载函数, 进行下载,
爬去过程中会有下载失败的, 所有我在爬去完毕后, 检查下载失败的, 再次进行下载,
最后, exec 包执行 cmd 命令 进行合成一个 ts 文件
- const request = require("request");
- const fs = require("fs");
- const { exec } = require('child_process');
- const emptyFile = [];
- const failDownload = [];
- function reload(results) {
- results.forEach(el => {
- let checkUrl = './download/' + el;
- // 检查文件是否已经存在
- if(fs.existsSync(checkUrl)) {
- // 获取文件信息
- const r = fs.statSync(checkUrl);
- // 如果大小为 0, 则是下载失败的
- if(r && r.size == 0) {
- emptyFile.push(el);
- // 删除下载失败的
- const del = fs.unlinkSync(checkUrl);
- if(del) {
- throw '删除 ts 文件异常'
- }
- else {
- console.log(el + '删除成功')
- }
- // 重新下载
- download(el)
- }
- }
- else {
- download(el)
- }
- });
- }
- // 这个合成函数在编辑中运行会报错, 暂且复制到 cmd 中运行的
- function composite() {
- // "/b": 表示按二进制合并; 不加就默认按字符转合并, 会出问题
- exec("copy /b H:\self-study \ 下载视频流 \ download\*.ts H:\self-study \ 下载视频流 \ download \ 冷血追击. ts", (error, stdout, stderr) => {
- if (error) {
- console.error(` 执行的错误: ${error}`);
- return;
- }
- console.log(`stdout: ${stdout}`);
- console.error(`stderr: ${stderr}`);
- });
- }
- function download(url) {
- const baseUrl = 'https://youku.com-qq.net/20190502/181_7ffa42fa/1000k/hls/';
- const downloadUrl = __dirname + '/download/' + url;
- request(baseUrl + url, (error, response, body) => {
- if(response) {
- failDownload.push(url);
- console.log(url + '下载成功')
- }
- if(error) {
- console.log(url + '下载失败')
- }
- })
- .pipe(fs.createWriteStream(downloadUrl))
- // 下载后, 按流直接写入本地文件
- }
- const reg = /(\w+\.ts)/mg;
- function getList(cb) {
- const getListFile = './download/getlist.txt';
- function doGetAgain () {
- // 获取 ts 分段配置文件
- request.get('https://youku.com-qq.net/20190502/181_7ffa42fa/1000k/hls/index.m3u8',(error, response, body) => {
- if(typeof body == 'string') {
- let results = body.match(reg);
- console.log(results);
- fs.writeFileSync(getListFile, results.join(','))
- cb && cb(results);
- console.log('从服务器获取')
- return results;
- }
- })
- }
- // 检车本地是否有该文件
- if(fs.existsSync(getListFile)) {
- let data = fs.readFileSync(getListFile, 'utf-8');
- if(data) {
- console.log('从本地获取');
- cb(data.split(','));
- }
- else {
- return doGetAgain(cb);
- }
- }
- return doGetAgain(cb);
- }
- function tickerGet(results) {
- const len = results.length -1;
- let i = 0;
- const ticker = setInterval(() => {
- if(i <= len) {
- download(results[i]);
- i++;
- }
- else {
- clearInterval(ticker);
- reload(results);
- }
- }, 3000)
- }
- getList(r => {
- // 定时获取下载
- tickerGet(r);
- // 重新下载失败的文件
- reload(r)
- // 合成
- composite();
- });
来源: http://www.bubuko.com/infodetail-3268533.html