title | date | updated | slug | categories | tags | |||||
---|---|---|---|---|---|---|---|---|---|---|
优学院直播自动签到 |
2022-09-02 15:27:04 -0700 |
2022-09-02 15:27:04 -0700 |
yxy-live-auto-sign |
|
|
优学院,老朋友了。优学院平台有个直播授课(用的 保利威 ),功能还算全面,但对于一些不感兴趣的课又或是老师全程讲PPT的课根本没有兴趣听下去,签到时间又飘忽不定,为了保住学分还只得注意着签到,不免让人心生反感。
第一次尝试直接 F12
是没有抓到接收签到信息和提交签到信息的数据包的,首先该平台没有使用 HTTP/HTTPS
协议来做这件事,而是使用了WebSocket
,也就意味着你在签到的时候才去抓包,而WebSocket
是一直连接着的,自然无法看到那条关键的记录,我们只需要重新刷新页面,筛选WS
即可看到,我们可以清楚的看到直播间的信息:哪位同学进入或退出直播间、发的消息、当然还有直播签到,虽然看起来一切都是明文,但每条消息前都有个数字前缀,通过分析,这个前缀是根据当前建立的WebSocket
信息来加密的,但调试时,涉及到访问变量或者跳过时我的浏览器直接卡死,等了几分钟才缓过来 根本进行不下去,建立WebSocket
连接时,需要token
验证以及header
于是就慢慢放弃了这条路。
也由于直播平台确实可以看到每位直播间用户(同学们)的在线时长(可以去保利威平台申请试用自己查证),如果很多同学不在线,但签到全勤也确实说不过去,与其这样不如直接从前端入手。
平台这点也确实偷懒了,签到交互界面一直存在,当收到服务器下发的签到信息,则显示出来,提交签到则消失,我们则可以直接去判断该交互界面的显示与否来决定是否触发签到操作(手动触发元素的点击事件)即可实现。
不用动脑子我们就可以写出如下代码:
const autoSignIntervalId = setInterval(() => {
if (document.querySelector(".plv-iar-btn-default.pws-btn-bg-color.pws-vclass-btn--primary").parentElement.parentElement.parentElement.parentElement.parentElement.style.display != "none") {
const btnList = document.querySelectorAll(".plv-iar-btn-default.pws-btn-bg-color.pws-vclass-btn--primary");
btnList.forEach(btn => {
if (btn.innerText == "立即签到") {
btn.click();
console.log("执行签到");
clearInterval(autoSignIntervalId);
}
});
}
}, 1000);
设置一个每秒执行的定时器,每次去看看签到交互界面出现了没,出现了就签到,再清除定时器就行(为什么写那么多的parentElement
,是因为确实没有id
,以及特殊的attribute
)
但我们转念一想,这样优雅吗?每秒都去执行还要判断,那么我们还不如这么写:
const autoSignIntervalId = setInterval(() => {
const btnList = document.querySelectorAll(".plv-iar-btn-default.pws-btn-bg-color.pws-vclass-btn--primary");
btnList.forEach(btn => {
if (btn.innerText == "立即签到") {
btn.click();
console.log("执行签到");
clearInterval(autoSignIntervalId);
}
});
}, 1000);
管他出不出现,我们就一直触发按钮点击事件就完了,能签到他自然就签到了,还省得去判断他出不出现。
我们应该去想,浏览器怎么这么懒,元素变化了自己不能告诉我吗?那我不就知道什么时候执行了,好巧不巧浏览器还真行
let observer = new MutationObserver(mutationList => {
if (document.querySelector(".plv-iar-btn-default.pws-btn-bg-color.pws-vclass-btn--primary").parentElement.parentElement.parentElement.parentElement.parentElement.style.display != "none") {
const btnList = document.querySelectorAll(".plv-iar-btn-default.pws-btn-bg-color.pws-vclass-btn--primary");
btnList.forEach(btn => {
if (btn.innerText == "立即签到") {
btn.click();
console.log("执行签到");
}
});
}
});
observer.observe(document.querySelector(".plv-iar-btn-default.pws-btn-bg-color.pws-vclass-btn--primary").parentElement.parentElement.parentElement.parentElement.parentElement, {
attributes: true,
attributeFilter: ["style"],
attributeOldValue: true,
childList: true,
subtree: true
});
虽然代码变长了,但也变强了,我们就像是给签到交互界面注册了一个回调函数,当他的style
变化了,就会告诉我们,我们再去执行就好了,就不用向上面那样一直在执行。
之前再写博客主题的时候也有去了解 MutationObserver
这个API
,那时候的需求是做跟随目录,但是这个API
貌似是监听页面从视口底部出现,与需求不相符,就没做深入了解,API
太多了,学不动了。
复制最后一块代码,按F12
打开浏览器开发者工具,粘贴到控制台回车运行,接下来就可以做你想做的事儿了,但是必修课和自己感兴趣的课一定不要这么做,无疑是放纵自己。
最后:用技术实现
的,也能用技术实现