Greasy Fork:超星网课全能打码 脚本解析
脚本信息
- 名称:超星网课全能打码
- 链接:https://greasyfork.org/zh-CN/scripts/380572
- 作者:Anubis Ja
- 版本:3.1.0
- 功能:各个页面出现的验证码打码。支持页面:[为保障您的账号安全,请输入验证码],[您的操作异常,请输入验证码],[课后习题提交频繁],[进入考试]
- 参数:key、打码超时(毫秒)、打码超时重试(次)、打码频率(毫秒/次)
- 代码地址:https://greasyfork.org/zh-CN/scripts/380572/code
功能实现分析
使用jQuery
中的load
方法监控img
元素的加载,通过canvas
截取验证码图片,上传到打码服务器,返回结果后填入验证码输入框,再使用click
方法点击提交按钮或直接执行超星特定函数(由于超星开发不规范,验证码提交的按钮可能没有id,元素选择上有困难,但按钮绑定了onclick属性,于是直接执行onclick中函数即可)。
beforeGet(中间流程)
function beforeGet(dom, page) { //验证码的dom信息,页面标号
if (setting.userkey == '') {
msg('打码key不能为空,请详细阅读<a href="https://greasyfork.org/zh-CN/scripts/380572" target="_blank">【脚本描述】</a>!', 'red');
return;
}
var img = imageBase64(dom); //Base64编码图片
setting.count = setting.error = 1; //初始化重试、错误次数
getCode(page, img); //打码
}
dama(验证码回填提交)
function dama(page, result) {
if (page == 1) {
$('#identifyCodeRandom').val(result); //回填
_self.continueGetTeacherAjax(); //调用超星的函数提交
setTimeout(check1, 2E3); //处理验证码错误弹窗
} else if (page == 2) {
if (result.length != 4) location.reload(); //处理打码长度不正确
$('#ucode').val(result); //回填
$('.submit').click(); //提交
} else if (page == 3) {
$('#code').val(result); //回填
$('#sub:visible')[0].click(); //提交
} else if (page == 4) {
$('[id$=identifyCodeRandom]:visible').val(result); //回填
$('[id$=startTestDiv] > a:visible')[0].click(); //提交
setTimeout(check4, 2E3); //处理验证码错误弹窗
} else if (page == 5) {
$('#numcode').val(result); //回填
}
}
check1、check4(处理验证码错误弹窗)
function check1() {
if ($('#chapterVerificationCodeTip:hidden').length) return; //如果验证码错误弹窗是隐藏的,不处理
_self.WAY.box.hide(); //调用超星的函数隐藏窗口
$('#chapterVerificationCodeTip').hide(); //调用超星的函数隐藏窗口
_self.showChapterVerificationCode(); //显示验证码弹窗
}
function check4() {
$('[id$=tipIdentifyCode]:visible').next().find('a')[0].click(); //点击确定,超星会自动弹出新的验证码
$('[name=examNumVerCode]:visible').click();
}
imageBase64(Base64编码图片)
function imageBase64(img) {
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
return canvas.toDataURL('image/png').substr(22);
}
msg(信息提示)
function msg(msg, color) {
var d = new Date(),
t = d.getHours().format() + ':' + d.getMinutes().format() + ':' + d.getSeconds().format();
msg = t + ' ' + msg; //生成当前时间
$div.children('div:last').append('<p style="color: ' + color + '">' + msg + '</p>'); //追加到div末尾
}
参考资料
jQuery 事件 - load() 方法
http://www.w3school.com.cn/jquery/event_load.asp
当指定的元素(及子元素)已加载时,会发生 load() 事件。
该事件适用于任何带有 URL 的元素(比如图像、脚本、框架、内联框架)。
根据不同的浏览器(Firefox 和 IE),如果图像已被缓存,则也许不会触发 load 事件。
jQuery 参考手册 - 选择器
http://www.w3school.com.cn/jquery/jquery_ref_selectors.asp
jQuery 元素选择器和属性选择器允许您通过标签名、属性名或内容对 HTML 元素进行选择。
在 HTML DOM 术语中: 选择器允许您对 DOM 元素组或单个 DOM 节点进行操作。