有没有办法抓取或抓取 m3u8 播放列表?

Is there a way to scraping or crawl the m3u8 playlist?

我是一名学生,正在尝试构建一个电影网站项目以供练习。

但我只知道电影的数据库会很大,所以我就想“如果我只是从另一个网站借用电影怎么办”,所以我查找并找到了一个名为“Scrape or Crawl Data”的术语”,当然,这是为了非商业目的,我只是想让我的项目发挥作用。因此,如果这样做违法或不正确,请在下方发表评论,我会考虑的。

但是如果可以的话,有什么办法可以得到m3u8播放列表吗? 我不知道该怎么做(老实说,完全不知道)。所以我真的需要一个指南或一些指导,我需要做的方向。

由于我的研究,我打算使用一些 cheerio、Axios,并尝试以某种方式解决它。

更具体地说,每当我播放视频时,如果我检查它,在“网络”选项卡中,它会包含一个名为 playlist.m3u8 的文件,其中包含许多小的 .ts 文件。我想以某种方式获取它并将其转移到我的项目中可观看。

playlist.m3u8 文件就是一个播放列表,包含有关视频的数据和视频链接 files/chunks,或指向包含该内容的块列表的链接。

根据您的项目,它可能已经内置了查看 m3u8 文件的方式,在基于浏览器的项目中,您只需将视频元素的 url 设置为 url .m3u8.

如果没有办法使用 m3u8 文件,您将必须下载解析器或自己编写解析器。

这是一个简单的 JS 解析器,它会按顺序读取每个 ts 并将它们附加到视频的末尾,因为它会忽略时序数据和所有其他额外信息,所以它会出现很多问题,但它的意思是一个简单的例子。

//This is a simple example that is non-reliable and should not be relied upon.

const fs = require('fs');
const http = require('http');

const source_domain = "http://sourcehost.com/";

const playlist_path = "playlist.m3u8";

var video_file = fs.createWriteStream("test.mp4");

GetPlaylist(source_domain + playlist_path); 

function GetPlaylist(url){
    return new Promise((resolve, reject) => {
        http.request(url, (res) => {
            var data = '';
        
            res.on('data', (chunk) =>{
                data += chunk;
            });
            
            res.on('end', async () => {
                var lines = data.split("\n");
                for(var line of lines){
                    if(line.indexOf(".ts") !== -1){
                        await GetChunk(source_domain + line);
                    }
                }
                video_file.end();
            });

            res.on('timeout', () => {
                reject('timeout');
            });
        }).end();
    });
}


function GetChunk(chunk_path){ 
    return new Promise((resolve, reject) => {
        http.request(chunk_path, (res) => {
            res.setEncoding('binary');
        
            res.on('data', (chunk) =>{
                video_file.write(chunk, 'binary');
            });
            
            res.on('end', () => {
                resolve();
            });

            res.on('timeout', () => {
                reject('timeout');
            });
        }).end();
    });
}