通途

教务网验证码识别,已适配西南交通大学(swjtu),石家庄铁道大学,新乡医学院三全学院,四川城市职业学院(scuvc),阿坝师范学院(旧版教务),四川国际标榜职业技术学院,四川交通职业技术学院(svtcc),四川工商学院(abtc)

目前為 2020-05-11 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name 通途
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.5.4
  5. // @description 教务网验证码识别,已适配西南交通大学(swjtu),石家庄铁道大学,新乡医学院三全学院,四川城市职业学院(scuvc),阿坝师范学院(旧版教务),四川国际标榜职业技术学院,四川交通职业技术学院(svtcc),四川工商学院(abtc)
  6. // @author kaka
  7. // @match http://jwc.swjtu.edu.cn/service/login*
  8. // @match *://jiaowu.swjtu.edu.cn/service/login*
  9. // @match http://jwc.swjtu.edu.cn/vatuu/YouthIndexAction?setAction=index
  10. // @match http://jwc.polus.edu.cn/service/login*
  11. // @match http://jwc.abtu.edu.cn/service/login*
  12. // @match http://jwb.sqmc.edu.cn/service/login*
  13. // @match http://jwc.svtcc.edu.cn/service/login*
  14. // @match http://jwc.scuvc.com/service/login*
  15. // @match http://jwxt.stbu.edu.cn/service/login*
  16.  
  17. // @match *.vatuu.com/service/login*
  18. // @match *.vvtuu.com/service/login*
  19. // @connect aip.baidubce.com
  20. // @connect localhost
  21. // @grant unsafewindow
  22. // @grant GM_xmlhttpRequest
  23. // @grant GM_getValue
  24. // @grant GM_setValue
  25. // @run-at document-start
  26. // ==/UserScript==
  27. (function() {
  28. 'use strict';
  29. let setting = {//改一改这个,应该能用于其他网站,慢慢适配
  30. ran_img : document.querySelector("#randomPhoto > img"), /*验证码图片元素*/
  31. ran_img_url:window.location.origin+'/vatuu/GetRandomNumberToJPEG?test='+new Date().getTime(),/*验证码图片请求url*/
  32. ran_text : document.getElementById('ranstring'),/*验证码填写元素*/
  33. other_data:['document.querySelector("#password")',/*其它必填项#######################自动处理,下次跟新再说(逃*/
  34. 'document.querySelector("#username")'],/*必须是字符串,目前想不到更好的解决办法*/
  35. submit:document.querySelector("#submit2"),/*登陆按钮*/
  36. nostop:true,/*错误后允许重试*/
  37. err_total:5, /*各环节允许最大错误*/
  38. autologin:false,//自动登录(不可用)开关
  39. debugger:0,//调试开关
  40. ocrurl: "https://aip.baidubce.com/rest/2.0/ocr/v1/webimage",//api地址
  41. ocrurl_1: "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic",//备用api
  42. apis:[['iKGARn6BhGgU82W9xzLUIatb','hES0Zae2iLdP1iotenC8zlGo9qA3r0Hc'],
  43. ['UjcQzcjSpyYGrXKyPy3dBdoW','65GqKnF5jH3QR9ZEIr8j1ppKWuDRLgI7'],
  44. ['Vt2YOiA6CZTnnpaZCEHLTTl6','LIeZdRFmg8odzPCLR8yPPdNeZDKA7yWM'],
  45. ['xCEG3OUq0mKzIThFiGPh9AES','mpCK1RI4sFIkX79QDDy6qO2GmCCGC6TS'],
  46. ],
  47. };
  48.  
  49.  
  50.  
  51.  
  52. function autologin(){
  53. if(other_data_done()){/*其它信息也填了就登陆*/
  54. setting.submit.click();
  55.  
  56. };
  57.  
  58. };
  59. function add_onload(){
  60. try{
  61. let img =document.querySelector("#randomPhoto > img")//再次添加监听
  62. img.addEventListener("load",function(){
  63. get_random_img(function( bs64_str){
  64. get_str(bs64_str)
  65.  
  66. })
  67. })
  68. }catch(e){}
  69. }
  70. function debug(){
  71. if(setting.debugger){
  72. const arg = Array.from(arguments);
  73. arg.unshift(`color: white; background-color:#2274A5`);
  74. arg.unshift('%c 通途:');
  75. console["info"].apply(console, arg);
  76. }
  77. }
  78. function enter_login(){
  79. document.onkeydown = function(ev){
  80. var e = ev || event;
  81. if(e.keyCode ==13){
  82. setting.submit.click();
  83. };
  84. }};
  85. function other_data_done(){
  86. if(eval(setting.other_data.join('.value&&')+'.value')){return true;};
  87. };
  88.  
  89. function get_random_img(callback){
  90. setting.runing=1
  91. let img= document.querySelector("#randomPhoto > img")
  92. debug(img)
  93. let canvas = document.createElement("canvas");
  94. canvas.width = img.width;
  95. canvas.height = img.height;
  96. let ctx = canvas.getContext("2d");
  97. ctx.drawImage(img, 0, 0, img.width, img.height);
  98. let ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
  99. let dataURL = canvas.toDataURL("image/"+ext);
  100. let bs64_str = dataURL.split(",")[1];
  101. callback(bs64_str);
  102.  
  103. };
  104. function get_access_url(){
  105. let randomapi = setting.apis[setting.ran_api_num];
  106. return 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+randomapi[0]+'&client_secret='+randomapi[1]
  107. };
  108.  
  109. function setCookie(cname, cvalue, exp) {
  110. var d = new Date();
  111. d.setTime(d.getTime() + (exp*1000)-5000);
  112. var expires = "expires="+d.toUTCString();
  113. document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
  114. };
  115.  
  116. function getCookie(cname) {
  117. var name = cname + "=";
  118. var ca = document.cookie.split(';');
  119. for(var i = 0; i < ca.length; i++) {
  120. var c = ca[i];
  121. while (c.charAt(0) == ' ') {
  122. c = c.substring(1);
  123. };
  124. if (c.indexOf(name) == 0) {
  125. return c.substring(name.length, c.length);
  126. };
  127. };
  128. return "";
  129. };
  130.  
  131. function get_access(){
  132. debug("api-num",setting.ran_api_num)
  133. debug("api-url",setting.ocrurl)
  134. let access_token = getCookie("access_token_"+setting.ran_api_num);
  135. if (access_token != "") {/*access未过期*/
  136. setting.access_token =access_token;
  137. } else {
  138. try{
  139. GM_xmlhttpRequest({
  140. method: "GET",
  141. url:get_access_url(),
  142. onload: function(response) {
  143. let access_token =JSON.parse(this.responseText)["access_token"];
  144. let expires =JSON.parse(this.responseText)["expires_in"];
  145. setCookie("access_token_"+setting.ran_api_num, access_token, expires);
  146. setting.access_token = access_token;
  147. }
  148. });
  149. }catch(err){
  150. debug("response1",response.responseText)
  151.  
  152. if( err_access_num<=setting.err_total){
  153. err_access_num+=1;
  154. get_access();
  155. }else{
  156. setting.ran_text.placeholder = '失败,请自行输入';
  157.  
  158. }
  159. }
  160. }
  161.  
  162. }
  163. function get_str(bs64_str){
  164. let request_url = setting.ocrurl + "?access_token=" + setting.access_token;
  165. let data = 'image='+encodeURIComponent(bs64_str);
  166. /*alert(encodeURIComponent(bs64_str));*/
  167. GM_xmlhttpRequest({
  168. method: 'POST',
  169. url: request_url,
  170. data: data,
  171. headers: {
  172. 'charset': 'UTF-8',
  173. "Content-Type": "text/plain"
  174. },
  175. onload: function(response) {
  176. /* console.log("baidu_response");*/
  177. debug(response.responseText)
  178. let temp = JSON.parse(response.responseText);
  179. if(temp['error_code']==17){
  180. debug('服务器请求超限',setting.ran_api_num)
  181. let lastapi=setting.apis[setting.ran_api_num]
  182. setting.apis[setting.ran_api_num]=0//标记超限的
  183. debug(setting.apis)
  184.  
  185. for(let i=0;i<setting.apis.length;i++){
  186.  
  187. if(setting.apis[i]!=0){
  188. setting.ran_api_num = i
  189. get_random_img(function( bs64_str){
  190. get_access();
  191. get_str(bs64_str);
  192. throw "超限"
  193. }
  194. )
  195. }
  196. }
  197. setting.ocrurl= setting.ocrurl_1//使用备用识别url
  198. setting.apis[setting.ran_api_num]=lastapi
  199. get_random_img(function( bs64_str){
  200. get_access();
  201. get_str(bs64_str);
  202.  
  203. }
  204. )
  205. setting.ran_text.placeholder = '今日请求超限';
  206. debug('无可用')
  207. return
  208. }else if(temp['error_code']&& temp['error_code']!= 18&& temp['error_code']!= 110){
  209. setting.ran_text.placeholder = '服务器访问出错';
  210. return
  211. }
  212. try{
  213.  
  214. let rand_str = temp['words_result'][0]['words'].trim();
  215. debug("解析结果",rand_str)
  216. if(rand_str.length == 4){
  217. setting.ran_text.value = rand_str; /*填写验证码 */
  218. if(other_data_done()&&setting.autologin){/*其它信息也填了就登陆*/
  219. setting.submit.click();
  220. };
  221. debug('已填写')
  222. add_onload()//添加监听
  223. }else{ /*重来*/
  224.  
  225. throw "解析失败";
  226.  
  227. };
  228. }catch(err){
  229. setTimeout(function(){
  230. if(setting.nostop){
  231. if(setting.err_num<=setting.err_total ){
  232. setting.err_num+=1;
  233. /*console.log(setting.err_num)*/
  234. setting.ran_text.placeholder = '失败,重试中...';
  235. getPhotoAgain();
  236. add_onload()
  237. }else{
  238. setting.ran_text.placeholder = '失败,请自行输入';
  239. return;
  240. }
  241. };
  242.  
  243. },200)
  244.  
  245. };
  246. }
  247. });
  248. };
  249. function init(){
  250. setting.runing=0;
  251. setting.err_num = 1;
  252. let err_access_num = 1;
  253. setting.ran_api_num = Math.floor(Math.random() * setting.apis.length);
  254. enter_login();
  255. document.querySelector("#ranstring").addEventListener('focus',function(){setting.nostop=false; setting.ran_text.placeholder = '检测到自行输入';})/*用户选择自己写时,阻止继续执行*/
  256. }
  257. function main(){
  258. let img =document.querySelector("#randomPhoto > img")
  259. debug(img)
  260. img.addEventListener("load",function(){
  261. setting.ran_text.placeholder = '尝试获取验证码中';
  262. get_random_img(function( bs64_str){
  263. get_access();
  264. get_str(bs64_str);
  265. });
  266. /*setInterval(autologin,3000)//适合自己用*/
  267. autologin();/*针对浏览器预先填写的用户*/
  268. // setInterval(add_onload,10);目的是验证码错误后再次尝试,但好像有点问题,如何区分谁改的img标签,脚本还是源网页
  269. })
  270. }
  271. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  272. init();
  273. main();
  274. let isrun= setInterval(function(){//发现会概率性不执行,推测是因为上面onload的锅,先加个检测
  275. console.log(setting.runing)
  276. if(setting.runing){
  277. clearInterval(isrun)
  278. }else{
  279. debug('run main')
  280. setting.ran_text.placeholder = '尝试获取验证码中';
  281. get_random_img(function( bs64_str){
  282. get_access();
  283. get_str(bs64_str);
  284. }
  285. )
  286. }
  287. },100)
  288.  
  289. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址