利用nodejs,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();
});