油猴的初次实践,添加按钮及事件获取需要的内容

675 阅读4分钟

事由

有时候,才看一些视频的时候,那些野路子的小众视频网站,可能由于资金问题,看视频的时候总是一卡一卡的。然后就想着干脆将想看的视频爬下来看吧,总比看一会卡十秒的观感好。但是由于这个网站有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()方法,将值传到粘贴板上面去。然后我就可以直接在调爬虫的时候,直接右键粘贴出参数了。省去我打开开发者工具找地址的操作。

image.png

总结

有时候,可能程序员都有这样的因有思维,都喜欢用最完美的方案去解决需求,我刚开始的时候也进入了这个思维,总想完全自动化,打开页面就自动显示我需要的数据。但由于技术原因,要完成到这样的层度,我需要花很大的力气去钻研js。但如果找一个方法,则省去了不少的事情,并能轻松实现自己的需求。所以,在动手前,还是要想清楚再动手,可能会为自己省下不少的时间。当然,如果只针对技术的话,还是可以用第一种方法尝试一下的。