李恒道 发表于 2021-12-13 10:39:19

[油猴脚本开发指南]实战秒杀快手视频提取

# 前言

这节课我们实战快手视频提取脚本

地址:https://www.kuaishou.com/profile/3x72uw4df7wdq8q

如果出现undefined多刷新基本,快手网页端做的不怎么好

强烈要求使用chrome!

另再次感谢cxxjackie

# 开始

我们先以一个视频为基础

![图片.png](data/attachment/forum/202112/13/101129vf55kqhrybgpqgkp.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

这个时候打印__vue__属性,发现不存在

![图片.png](data/attachment/forum/202112/13/101159u82zkd62pqc5wdkp.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

我们慢慢往上级找

再多层parent找到了属性,这时候打印$el查看对应dom元素,发现class是video-card那个class类

![图片.png](data/attachment/forum/202112/13/101255r7vpi6pmpzm6lnml.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

我们看看数据怎么样

![图片.png](data/attachment/forum/202112/13/101739kgqh1tbnzcctct4c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

发现存在数据,看一下有没有视频地址,发现在photo的photoUrl是无水印视频地址

这个时候我们还是之前的思路

收集dom元素列表,然后开始mutationobserve监测元素改变状态,直接对抄之前的抖音脚本

```javascript
function ControlShowCheckAndNew(target){
    console.log('target',target)
}
let list=document.querySelectorAll('.video-card')
const targetNode = document.querySelector('.user-photo-list')
// 观察器的配置(需要观察什么变动)
const config = {
childList: true, // 观察目标子节点的变化,添加或删除
attributes: true, // 观察属性变动
subtree: true, //默认是false,设置为true后可观察后代节点
};

// 当观察到变动时执行的回调函数
const callback = function(mutationsList, observer) {
// Use traditional 'for loops' for IE 11
console.log('mutationsList',mutationsList)
for(let mutation of mutationsList) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((item)=>{
ControlShowCheckAndNew(item)
})
}
}
};
// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(callback);
// 以上述配置开始观察目标节点
observer.observe(targetNode, config);
unsafeWindow.onload=()=>{
//处理循环
list.forEach((item)=>{
ControlShowCheckAndNew(item)
})
}
```

我们测试一下,发现报错了

![图片.png](data/attachment/forum/202112/13/101950xc1cgspztp3pphox.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

根据debugger调试,可以确定是没找到元素的事情,存在一个延时加载的问题,上去直接一个setinterval,检测出来元素之后再执行我们的逻辑

```javascript

function ControlShowCheckAndNew(target){
    console.log('target',target)
}
function wraprun(){
    let list=document.querySelectorAll('.video-card')
    const targetNode = document.querySelector('.user-photo-list')
    // 观察器的配置(需要观察什么变动)
    const config = {
      childList: true, // 观察目标子节点的变化,添加或删除
      attributes: true, // 观察属性变动
      subtree: true, //默认是false,设置为true后可观察后代节点
    };

    // 当观察到变动时执行的回调函数
    const callback = function(mutationsList, observer) {
      // Use traditional 'for loops' for IE 11
      console.log('mutationsList',mutationsList)
      for(let mutation of mutationsList) {
            if (mutation.type === 'childList') {
                mutation.addedNodes.forEach((item)=>{
                  ControlShowCheckAndNew(item)
                })
            }
      }
    };
    // 创建一个观察器实例并传入回调函数
    const observer = new MutationObserver(callback);
    // 以上述配置开始观察目标节点
    observer.observe(targetNode, config);
    unsafeWindow.onload=()=>{
      //处理循环
      list.forEach((item)=>{
            ControlShowCheckAndNew(item)
      })
    }
}

let setint=setInterval(()=>{
    let list=document.querySelectorAll('.video-card')
    if(list!=null&&list.length!==0){
      wraprun()
      clearInterval(setint)
    }

},1000)
```

这时候根据测试,onload回调没有执行,因为页面的图片没有加载完全,我们下拉滚动条才会开始加载视频图片,所以图片没加载完不属于onload状态,这里也没有什么特殊要求,我就直接去掉onload就好了。

然后我们开始实现ControlShowCheckAndNew函数,直接对抄一下之前的抖音的

```javascript
let saveurl={}
function ControlShowCheckAndNew(target){
    if(target.className.indexOf('injectvideo')!=-1){
      return true;
    }
    if(target.className.indexOf('control-pos')!=-1){
      return true;
    }
    const prop = '__vue__'
    if(prop===undefined){
      return;
    }
    let info=target.data
    if(info===undefined){
      console.log('test')
    }
    let videourl=info.photo.photoUrl
    videourl='https://'+videourl.replace('https://','').replace('http://','').replace('//','')
    target.classList.add('injectvideo')
    var select=document.createElement('label')
    select.className='container control-pos'
    select.innerHTML=` <inputtype="checkbox"><div class="checkmark"></div>`
    target.append(select)
    select.onclick=()=>{
      console.log('选中变化了',select.children.checked)
      if(select.children.checked){
            //选中
            saveurl=true;
      }else{
            //未选中
            if(saveurl){
                delete saveurl
            }
      }
    }
}
```

这里几乎就是对抄之前的,简单修改了一下逻辑

之后我们之前用了样式,所以这里也要使用,简单修改一下css样式,贴进来

```javascript
let cssstyle = document.createElement("style");
cssstyle.innerHTML =(`
篇幅太长省略
`);
document.body.appendChild(cssstyle);
```

测试一下发现可以看到这个了

![图片.png](data/attachment/forum/202112/13/103246mi1qtaav7i17t1x7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

接下来开始插入按钮

因为页面是一个延迟加载的,我们想插入到已关注的下方,所以也要判断,这里我直接加在setinterval里了

两个条件都满足才执行

```javascript
let setint=setInterval(()=>{
    let list=document.querySelectorAll('.video-card')
    if(list!=null&&list.length!==0){
      if(document.querySelector('.user-detail')!==null){
            wraprun()
            wrapdrawbutton()
            clearInterval(setint)
      }
    }

},1000)
```

如果找到了wraprun就开始监听页面插入,以及绘制目前的视频的单选框

并且wrapdrawbutton函数开始绘制按钮

接下来我们开始写wrapdrawbutton函数

```javascript
function wrapdrawbutton(){
    let parenttagert=document.querySelector('.user-detail')
    let div=document.createElement("div");
    div.innerHTML=`<div class="follow-button user-info-follow" data-v-68cd9209="" style="margin-top: 10px;" data-v-58fa4879="">批量下载</div>`
    div.onclick=function(event){
      let size=Object.keys(saveurl)
      let text=size.join('\n')
      GM_setClipboard(text)
      alert('已设置到剪辑版共'+size.length+"个")
    };
    parenttagert.append(div);
}
```

直接复制一下抖音的,然后修改一下div内容。

跑一下,成功!

那我们这节课就已经讲解完毕了!![图片.png](data/attachment/forum/202112/13/103851c2j2ymgi8vfjmu8s.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/300 "图片.png")

# 结语

撒花~

国家电网0 发表于 2021-12-13 11:56:12

ggnb哈哈哈

李恒道 发表于 2021-12-13 15:58:07

国家电网0 发表于 2021-12-13 11:56
ggnb哈哈哈

我猜你是用手机回的

国家电网0 发表于 2021-12-13 16:00:39

李恒道 发表于 2021-12-13 15:58
我猜你是用手机回的

确实,手机会更方便些
页: [1]
查看完整版本: [油猴脚本开发指南]实战秒杀快手视频提取