Greasy Fork is available in English.
为途教务系统验证码识别
- // ==UserScript==// @name 通途// @namespace http://tampermonkey.net/// @version 2.5.8// @description 为途教务系统验证码识别// @author kaka// @match http://jwc.swjtu.edu.cn/service/login*// @match *://jiaowu.swjtu.edu.cn/service/login*// @match http://jwc.swjtu.edu.cn/vatuu/YouthIndexAction?setAction=index// @match http://jwc.polus.edu.cn/service/login*// @match http://jwc.abtu.edu.cn/service/login*// @match http://jwb.sqmc.edu.cn/service/login*// @match http://jwc.svtcc.edu.cn/service/login*// @match http://jwc.scuvc.com/service/login*// @match http://jwxt.stbu.edu.cn/service/login*// @match *.vatuu.com/service/login*// @match *.vvtuu.com/service/login*// @connect aip.baidubce.com// @connect localhost// @grant unsafeWindow// @grant GM_xmlhttpRequest// @grant GM_getValue// @grant GM_setValue// @run-at document-end// ==/UserScript==(function() {'use strict';let setting = {//改一改这个,应该能用于其他网站,慢慢适配////////////////////////////////////////////////////////////////////////////////////////////user-settingran_img:function(){return document.querySelector("#randomPhoto > img")}, /*验证码图片元素*/ran_img_url:window.location.origin+'/vatuu/GetRandomNumberToJPEG?test='+new Date().getTime(),/*验证码图片请求url*/ran_text:function(){return document.getElementById('ranstring')},/*验证码填写元素*/other_data:['document.querySelector("#password")',/*其它必填项#######################自动处理,下次跟新再说(逃*/'document.querySelector("#username")'],/*必须是字符串,目前想不到更好的解决办法*/submit:document.querySelector("#submit2"),/*登陆按钮*/add_onload_listener:1,//是否需要在切换验证码后对图片元素监听autologin:false,//自动登录开关//////////////////////////////////////////////////////////////////////////////////////////////other-settingnostop:true,/*错误后允许重试*/err_total:10, /*各环节允许最大错误*/debugger:0,//调试开关done:0,ocrurl: "https://aip.baidubce.com/rest/2.0/ocr/v1/webimage",//api地址ocrurl_1: "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic",//备用apiapis:[['iKGARn6BhGgU82W9xzLUIatb','hES0Zae2iLdP1iotenC8zlGo9qA3r0Hc'],],};////////////////////////////////////////////////////////////////其它网址匹配if(/bslc.lib.swjtu.edu.cn/.test(window.location.href)){debug('lib')setting.ran_img= function(){return document.querySelector("#kaptcha")}setting.ran_text= function(){return document.querySelector("#code")}setting.ran_url= "https://bslc.lib.swjtu.edu.cn/uas/kaptcha.jpg"setting.other_data= ['document.querySelector("#userid")','document.querySelector("#password")']setting.submit= document.querySelector("#form1 > div:nth-child(10) > button")//setting.autologin=true,//自动登录开关}/////////////////////////////////////////////////////////////function autologin(){if(other_data_done()){/*其它信息也填了就登陆*/setting.submit.click();};};function add_onload(){if(setting.add_onload_listener){try{let img =setting.ran_img()//再次添加监听img.addEventListener("load",function(){get_random_img(function( bs64_str){get_str(bs64_str)})})}catch(e){}}}function debug(){if(setting.debugger){const arg = Array.from(arguments);arg.unshift(`color: white; background-color:#2274A5`);arg.unshift('%c 通途:');console["info"].apply(console, arg);}}function enter_login(){document.onkeydown = function(ev){var e = ev || event;if(e.keyCode ==13){setting.submit.click();};}};function other_data_done(){if(eval(setting.other_data.join('.value&&')+'.value')){return true;};};function get_random_img(callback){setting.runing=1let img= setting.ran_img()debug(img)let canvas = document.createElement("canvas");canvas.width = img.width;canvas.height = img.height;let ctx = canvas.getContext("2d");ctx.drawImage(img, 0, 0, img.width, img.height);let ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();let dataURL = canvas.toDataURL("image/"+ext);let bs64_str = dataURL.split(",")[1];callback(bs64_str);};function get_access_url(){let randomapi = setting.apis[setting.ran_api_num];return 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+randomapi[0]+'&client_secret='+randomapi[1]};function setCookie(cname, cvalue, exp) {var d = new Date();d.setTime(d.getTime() + (exp*1000)-5000);var expires = "expires="+d.toUTCString();document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";};function getCookie(cname) {var name = cname + "=";var ca = document.cookie.split(';');for(var i = 0; i < ca.length; i++) {var c = ca[i];while (c.charAt(0) == ' ') {c = c.substring(1);};if (c.indexOf(name) == 0) {return c.substring(name.length, c.length);};};return "";};function get_access(){debug("api-num",setting.ran_api_num)debug("api-url",setting.ocrurl)let access_token = getCookie("access_token_"+setting.ran_api_num);if (access_token != "") {/*access未过期*/setting.access_token =access_token;} else {try{GM_xmlhttpRequest({method: "GET",url:get_access_url(),onload: function(response) {let access_token =JSON.parse(this.responseText)["access_token"];let expires =JSON.parse(this.responseText)["expires_in"];setCookie("access_token_"+setting.ran_api_num, access_token, expires);setting.access_token = access_token;}});}catch(err){debug("response1",response.responseText)if( err_access_num<=setting.err_total){err_access_num+=1;get_access();}else{setting.ran_text().placeholder = '失败,请自行输入';}}}}function get_str(bs64_str){if(setting.done){debug('已填写,取消操作')return}let request_url = setting.ocrurl + "?access_token=" + setting.access_token;let data = 'image='+encodeURIComponent(bs64_str);/*alert(encodeURIComponent(bs64_str));*/GM_xmlhttpRequest({method: 'POST',url: request_url,data: data,headers: {'charset': 'UTF-8',"Content-Type": "text/plain"},onload: function(response) {/* console.log("baidu_response");*/debug(response.responseText)let temp = JSON.parse(response.responseText);if(temp['error_code']==17){debug('服务器请求超限',setting.ran_api_num)let lastapi=setting.apis[setting.ran_api_num]setting.apis[setting.ran_api_num]=0//标记超限的debug(setting.apis)for(let i=0;i<setting.apis.length;i++){if(setting.apis[i]!=0){setting.ran_api_num = iget_random_img(function( bs64_str){get_access();get_str(bs64_str);throw "超限"})}}setting.ocrurl= setting.ocrurl_1//使用备用识别urlsetting.apis[setting.ran_api_num]=lastapiget_random_img(function( bs64_str){get_access();get_str(bs64_str);})setting.ran_text().placeholder = '今日请求超限';debug('无可用')return}else if(temp['error_code']&& temp['error_code']!= 18&& temp['error_code']!= 110){setting.ran_text().placeholder = '服务器访问出错';return}try{let rand_str = temp['words_r###lt'][0]['words'].trim();debug("解析结果",rand_str)if(rand_str.length == 4){setting.ran_text().value = rand_str; /*填写验证码 */if(other_data_done()&&setting.autologin){/*其它信息也填了就登陆*/setting.submit.click();};debug('已填写')setting.done=1//add_onload()//添加监听}else{ /*重来*/throw "解析失败";};}catch(err){setTimeout(function(){if(setting.nostop){if(setting.err_num<=setting.err_total ){setting.err_num+=1;debug('重试次数:'+setting.err_num)setting.ran_text().placeholder = '失败,重试中...';//if(setting.done){debug('已填写,取消操作') return}setting.ran_img().click()//切换验证码add_onload()}else{setting.ran_text().placeholder = '失败,请自行输入';return;}};},200)};}});};function init(){setting.runing=0;setting.err_num = 1;let err_access_num = 1;setting.ran_api_num = Math.floor(Math.random() * setting.apis.length);enter_login();debug(setting.ran_text())//setting.ran_text().addEventListener('focus',function(){setting.nostop=false; setting.ran_text().placeholder = '检测到自行输入';})/*用户选择自己写时,阻止继续执行*/}function main(){let img =setting.ran_img()debug(img)img.addEventListener("load",function(){setting.ran_text().placeholder = '尝试获取验证码中';get_random_img(function( bs64_str){get_access();get_str(bs64_str);});/*setInterval(autologin,3000)//适合自己用*/autologin();/*针对浏览器预先填写的用户*/// setInterval(add_onload,10);目的是验证码错误后再次尝试,但好像有点问题,如何区分谁改的img标签,脚本还是源网页})}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////init();main();var yalert = window.alertfunction newalert(msg){if('验证码输入不正确' == msg&&setting.nostop){debug('检测到alert,验证码输入不正确,开始执行main',msg)setting.ran_text().value = ''setting.done = falsesetting.autologin = truesetting.ran_img().click()//切换验证码add_onload()setting.err_num+=1;}else{yalert(msg)}}unsafeWindow.alert = newalertlet isrun= setInterval(function(){//发现会概率性不执行,推测是因为上面onload的锅,先加个检测console.log(setting.runing)if(setting.runing){clearInterval(isrun)}else{debug('run main')setting.ran_text().placeholder = '尝试获取验证码中';get_random_img(function( bs64_str){get_access();get_str(bs64_str);})}},100)})();