事由
有时候,才看一些视频的时候,那些野路子的小众视频网站,可能由于资金问题,看视频的时候总是一卡一卡的。然后就想着干脆将想看的视频爬下来看吧,总比看一会卡十秒的观感好。但是由于这个网站有5秒盾,技术有限过不了,曾经用过一些第三方库能过,但又突然不行了。然后爬视频都是手动开开发者工具,将m3u8的地址搞下来,然后下载视频的。
鉴于每次都要打开开发者工具去找链接,心想太累了,可不可以将地址根据我爬虫脚本的参数格式直接生成呢。然后就想到了用油猴去帮我了。
由于对js也不熟悉,然后就开启了自己的js学习之路了。
经过与弯路
经过页面元素的分析, m3u8的地址是在<video>标签里 的src属性中的。但这个标签是js渲染的,也就是在页面完成加载后,这个标签还不一定有。所以刚开始在油猴脚本中直接getElementByName是获取不了的。然后就研究了一番怎么去监控页面元素变化的方法。
const target = document.querySelector(".mantine-Col-root");
let observer = new MutationObserver(function (mutations) {
console.log("mutations", mutations);
var newArr = mutations.filter(function (item) {
return item.target === 'video#fPlayer';
})
for (var i = 0; i < mutations.length; i++) {
console.log(mutations[i]);
}
console.log("filter",newArr)
})
});
observer.observe(target, {
childList: true,
subtree:true,
attributes:false
});
在JS中有一个MutationObserver类,通过该类可以生成一个服务,只要在调用该服务的observe方法的时候,传入需要监控的元素节点,则可以监控该该元素树的变化了。
正当我准备针对监控到的变化来处理我的需求的时候,突然脑子一闪,发现自己将问题复杂化了。鉴于我的业务场景,应该是这样的。
我打开了一个视频 -> 需要下载下来观看 ->获取并自动生成脚本参数 -> 开启爬虫下载
这是我的使用场景,也就是说,当我想下载视频 的时候,页面肯定是已渲染完成的,没必要去监控页面元素的变化再过滤出我需要的信息。我只要在页面上添加一个按钮,当我看到想下载的视频的时候,此时元素肯定已经有了,再点击按钮获取我的数据,并直接传给粘贴板,我就可以直接使用了。这样逻辑就简单多了,也没必要去做元素的监控了。
最后成果
//获取需要添加按钮的节点对象
let target = document.querySelector(".mantine-Col-root");
let elemRoot= document.getElementsByTagName("article")[0];
//let target=document.querySelector('.mantine-Col-root')
//创建按钮
var inputbtn = document.createElement('input');
inputbtn.id="btn";
inputbtn.type="button";
inputbtn.value="按钮";
target.appendChild(inputbtn);
//创建文本框
var inputtext = document.createElement("input" );
inputtext.type = "text" ;
inputtext.id = "inputText" ;
inputtext.value = "这个文本框是JS创建的" ;
target.appendChild(inputtext);
//获取当前页面的链接 业务需要
var currentUrl = window.location.href;
//为按钮添加点击事件
inputbtn.addEventListener('click', function (e) {
// But only alert for elements that have an alert-button class
let a=document.getElementById('fPlayer')
let m3u8url=a.getElementsByTagName('source')[0].src
console.log(a.getElementsByTagName('source')[0].src);
let fullUrl=currentUrl+' "'+m3u8url+'"'
inputtext.value=currentUrl+' "'+m3u8url+'"'
navigator.clipboard.writeText(fullUrl)
所以最后成果变成了上述代码的样子,在油猴脚本中,创建了一个按钮,和一个文本框(其实也不是必须,就为了确认脚本生效的反馈)。然后为按钮添加点击事件,点击后将m3u8的地址从src中取出来,然后再通过navigator.clipboard.writeText()方法,将值传到粘贴板上面去。然后我就可以直接在调爬虫的时候,直接右键粘贴出参数了。省去我打开开发者工具找地址的操作。
总结
有时候,可能程序员都有这样的因有思维,都喜欢用最完美的方案去解决需求,我刚开始的时候也进入了这个思维,总想完全自动化,打开页面就自动显示我需要的数据。但由于技术原因,要完成到这样的层度,我需要花很大的力气去钻研js。但如果找一个方法,则省去了不少的事情,并能轻松实现自己的需求。所以,在动手前,还是要想清楚再动手,可能会为自己省下不少的时间。当然,如果只针对技术的话,还是可以用第一种方法尝试一下的。