目前视频网站基本没有放出 mp4 直链的直球网站,都是请求 m3u8 做视频分段。

基于海阔播放器的特性,拿到 m3u8 就是成功。

接下来用我做的第一个嗅探来进行详解

P站的 m3u8 地址是放在id为mobileContainer的 div 下第一个 script 中,我们需要获取这个 script 并使用eval()函数将变量声明到规则里。

var js = parseDomForHtml(html,"[id=mobileContainer]&&script&&Html")
eval(js);

此时遇到的第一个问题是一个变量报错,提示说变量 playerObjList 没有声明,检测网页代码可以知道 playerObjList 这个变量是在 header 的 script 中就声明了,执行mobileContainer下的  script 确实没有办法获得 playerObjList 的声明,因此需要在规则里声明一次,避免报错。

// 这个变量定义在下面执行 script 的上方,没有被读取执行,需要手动声明避免报错
var playerObjList = {}
var js = parseDomForHtml(html,"[id=mobileContainer]&&script&&Html");
eval(js);

接下来可以了解到储存有视频地址的变量名是qualityItems_后面接一串数字,数字每次加载页面都会随机变化,根本无法捕捉,所以需要将其替换为简单字符串。

var playerObjList = {}
var js = parseDomForHtml(html,"[id=mobileContainer]&&script&&Html").replace(/var qualityItems_.*?=/,'var qualityItems =');
eval(js);
var list = JSON.parse(qualityItems)

这样视频源变量名就是qualityItems了,此时它是一个json字符串,所以用JSON.parse()将其转为数组

然后就可以根据不同的清晰度来分配频道了

var playerObjList = {}

var js = parseDomForHtml(html,"[id=mobileContainer]&&script&&Html").replace(/var qualityItems_.*?=/,'var qualityItems =');
eval(js);
var list = JSON.parse(qualityItems)

list.forEach(item => {
    // 1080p 的 url 为空
    if (item.url) {
        d.push({
            title: item.text,
            url: item.url,
            col_type: 'text_2'
        });
    }
})

需要注意的是大部分1080p对应的 url 为空,需要过滤一下。

最后放上完整的二级解析:

js:
var res = {};
var d = [];
var html = getResCode();

var des_title = parseDomForHtml(html, '.inlineFree&&Text');
var des_pic = parseDom(html, '#videoPlayerPlaceholder&&img&&src');
var des_desc = parseDomForHtml(html, '.inlineFree&&Text');
var meta = parseDomForHtml(html, '[name=adsbytrafficjunkycontext]&&data-context-category');

d.push({
	title: des_title,
    desc: meta,
    pic_url: des_pic,
	url: des_pic,
	col_type: 'pic_1'
});

// 这个变量定义在下面执行 script 的上方,没有被读取执行,需要手动声明避免报错
var playerObjList = {}
// 获取视频播放地址的变量并执行
var js = parseDomForHtml(html,"[id=mobileContainer]&&script&&Html").replace(/var qualityItems_.*?=/,'var qualityItems =');
eval(js);
var list = JSON.parse(qualityItems)

list.forEach(item => {
    // 1080p 的 url 为空
    if (item.url) {
        d.push({
            title: item.text,
            url: item.url,
            col_type: 'text_2'
        });
    }
})

res.data = d;
setHomeResult(res);

海阔视界免嗅探


不知天在水,清梦压星河