问卷星自动答卷Tampermonkey插件

时间:2024-03-12 10:56:11

地址https://www.wjx.cn/vm/tzzn4o3.aspx需将vm改成vj

  1 // ==UserScript==
  2 // @name         问卷星自动随机答题
  3 // @version      0.4
  4 // @description 全自动填写问卷星的问卷,支持自定义填空答案,平均两三秒填写一份问卷,可多开几个标签同时刷
  5 // 已适配题型
  6 // 表格
  7 //  - 单选
  8 //  - 多选
  9 // 单选
 10 // 多选
 11 // 星星
 12 // 下拉
 13 // 拉条
 14 // 填空 默认为空
 15 // 排序
 16 // 图片
 17 // @author       ZainCheung
 18 // @include     https://www.wjx.cn/jq/*.aspx
 19 // @include     https://www.wjx.cn/vj/*.aspx
 20 // @include     https://www.wjx.cn/hj/*.aspx
 21 // @include     https://www.wjx.cn/wjx/join/complete.aspx*
 22 // @grant        none
 23 // @namespace http://tampermonkey.net/
 24 // ==/UserScript==
 25 
 26 (function() {
 27     \'use strict\';
 28 
 29     // 配置填空的答案项,如果不配置,默认填无
 30     var config = [
 31         {
 32             id: 1,//第一题:您的性别?
 33             answer: ["男","女"]//随机选出一个答案
 34         },
 35         {
 36             id: 2,//第二题:您的年龄?
 37             answer: ["25岁以下","25~35岁","35~50岁","50岁以上"]
 38         },
 39         {
 40             id:3,//第三题:您的职业?
 41             answer: ["学生","上班族","个体户","其他"]
 42         },
 43         {
 44             id: 4,//第四题:您旅游时会购买文创用品(旅游纪念品)吗?
 45             answer: ["会","不会"]
 46         },
 47         {
 48             id: 5,//第五题:您了解文创用品(旅游纪念品)吗?
 49             answer: ["了解","一般","听说过","不了解"]
 50         },
 51         {
 52             id: 6,//第六题:您一般会花费多少钱购买文创用品?
 53             answer: ["100元以下","100~200","200~300","300元以上"]
 54         },
 55         {
 56             id: 7,//第七题:您倾向于在哪里购买文创用品(旅游纪念品)?[多选题]
 57             answer: ["文具店","礼品店","创意生活馆","小商品市场","夜市等","淘宝等","其他"]
 58         },
 59         {
 60             id: 8,//第八题:影响您购买的主要因素? [ 多选题]
 61             answer: ["实用性","外观","创意","价格","潮流","其他"]
 62         },
 63         {
 64             id: 9,//第九题:您比较喜欢什么质感的文创用品(旅游纪念 品) ? [多选题]
 65             answer: ["陶瓷","塑料木质","玻璃","布艺","其他"]
 66         },
 67         {
 68             id: 10,//第十题:您购买文创用品(旅游纪念品)重点考虑的因素
 69             answer: ["价格","造型","功能","其他"]
 70         }
 71     ];
 72 
 73 
 74 
 75     //答题结束,则打开新的问卷
 76     (function openNew() {
 77         var currentURL = window.location.href;
 78         var pat = /complete\.aspx\?activityid=(\d+)/;
 79         var obj = pat.exec(currentURL);
 80         if (obj) {
 81             window.location.href = "https://www.wjx.cn/jq/" + obj[1] + ".aspx";
 82         } else {
 83             console.log("not pat", obj);
 84         }
 85     })();
 86 
 87 
 88     var currentURL = window.location.href;
 89     //自动转为电脑网页版
 90     (function redirect() {
 91         try {
 92             var pat = /(https:\/\/www\.wjx\.cn\/)(jq|m)(.*)/g;
 93             var obj = pat.exec(currentURL);
 94             if (obj[2] == "m") {
 95                 console.log("redirect now");
 96                 window.location.href = obj[1] + "jq" + obj[3];
 97             } else {
 98                 console.log("do!");
 99             }
100         } catch (error) {}
101     })();
102 
103 
104     /**
105      *
106      *
107      * @param {int} min The minimum value in the range
108      * @param {int} max The maxmum value in the range
109      * @return {int} Return Returns a random number within this range (both include)
110      */
111     function randint(min, max) {
112         return Math.floor(Math.random() * (max - min + 1) + min);
113     }
114 
115     function getRandomArrayElements(arr, count) {
116         var shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;
117         while (i-- > min) {
118             index = Math.floor((i + 1) * Math.random());
119             temp = shuffled[index];
120             shuffled[index] = shuffled[i];
121             shuffled[i] = temp;
122         }
123         return shuffled.slice(min);
124     }
125 
126 
127     /**
128      * @description 该函数用于自动选择
129      */
130     function RandomChoose() {
131         /**
132          * @name 普通单选题随机选择
133          * @param {object}  subject single subject
134          */
135         this.singleChoose = function(subject) {
136             if (subject.querySelectorAll("img")[0]) { //带有图片的,无法直接click 标签<li>
137                 var img = subject.querySelectorAll("img");
138                 img[randint(0, img.length - 1)].click();
139             } else {
140                 var list = subject.querySelectorAll("li");
141                 var no;
142                 for(var i = 0; i < list.length; i++){
143                     if(list[i].querySelector(".underline") != null){
144                         no = i;
145                     }
146                 }
147                 var index = randint(0, list.length - 1);
148                 while(index == no){index = randint(0, list.length - 1);}
149                 list[index].click();
150 
151             }
152         }
153 
154         /****
155          * @name    普遍多选题随机选择
156          * @param {object}  subject single subject
157          *
158          */
159         this.multiChoose = function(subject) {
160             var list = subject.querySelectorAll("li");
161             var arr = new Array();
162             for (var i = 0; i < list.length; i++) {
163                 if (list[i].querySelectorAll("input")[0].checked == true) {
164                     list[i].click();
165                 }
166                 arr.push(list[i]);
167             }
168             var times = randint(3, arr.length - 1); // 多选题选择数量,一般不小于3
169             var indexAry = getRandomArrayElements(arr, times);//准备选中的项
170             var no;//禁止项
171             for(var j = 0; j < indexAry.length; j++){
172                 if(indexAry[j].querySelector(".underline") != null){//去除多选框里需要填空的项
173                     console.log(indexAry[j]);
174                     no = j;
175                 }
176             }
177             for (i = 0; i < indexAry.length; i++) {
178                 if (indexAry[i].querySelectorAll("input")[0].checked == false && (i != no)) {
179                     indexAry[i].click();
180                 }
181             }
182 //             for (i = 0; i < times; i++) {
183 //                 var randomChoose = arr.splice(randint(0, arr.length - 1), 1)[0];
184 //                 if (randomChoose.querySelectorAll("input")[0].checked == false) {
185 //                     randomChoose.click();
186 //                 }
187 //             }
188         }
189 
190 
191 
192         //随机排序题
193         this.randomSort = function(subject) {
194             var list = subject.querySelectorAll("li");
195             var arr = new Array();
196             for (var i = 0; i < list.length; i++) {
197                 list[i].querySelectorAll("input")[0].checked = false;
198                 list[i].querySelectorAll("span")[0].classList.remove("sortnum-sel"); //事实上这个只是一个样式,真正选择在于checkd = true || false
199                 arr.push(list[i]);
200             }
201             for (i = 0; i < list.length; i++) {
202                 var randomChoose = arr.splice(randint(0, arr.length - 1), 1)[0];
203                 randomChoose.querySelectorAll("input")[0].checked = true;
204                 randomChoose.querySelectorAll("span")[0].classList.add("sortnum-sel");
205                 randomChoose.querySelectorAll("span")[0].innerHTML = i + 1;
206             }
207         }
208 
209         //表格单选
210         this.martixSingleChoose = function(subject) {
211                 var tr = subject.querySelectorAll("tbody > tr");
212                 for (var i = 0; i < tr.length; i++) {
213                     var td = tr[i].querySelectorAll("td");
214                     td[randint(0, td.length - 1)].click();
215                 }
216             }
217             //表格多选
218         this.martixMultiChoose = function(subject) {
219             var tr = subject.querySelectorAll("tbody > tr");
220             for (var i = 0; i < tr.length; i++) {
221                 var td = tr[i].querySelectorAll("td");
222                 var arr = new Array();
223                 for (var j = 0; j < td.length; j++) {
224                     td[j].querySelectorAll("input")[0].checked = false;
225                     td[j].querySelectorAll("a")[0].classList.remove("jqChecked");
226                     arr.push(td[j]);
227                 }
228 
229                 var times = randint(3, arr.length - 1); // 多选题选择数量,一般不小于3
230                 for (var k = 0; k < times; k++) {
231                     var randomChoose = arr.splice(randint(0, arr.length - 1), 1)[0];
232                     randomChoose.querySelectorAll("input")[0].checked = true;
233                     randomChoose.querySelectorAll("a")[0].classList.add("jqChecked");
234                 }
235                 console.log(times);
236             }
237         }
238         this.martixStar = function(subject) {
239             var tr = subject.querySelectorAll("tbody > tr");
240             for (var i = 0; i < tr.length; i++) {
241                 var list = tr[i].querySelectorAll("li");
242                 var rnnum = randint(0, list.length - 1);
243                 list[rnnum].click();
244                 console.log(i, rnnum);
245             }
246         }
247 
248         this.dropdownSelect = function(subject) {
249             var select = subject.querySelectorAll("select")[0];
250             var rnnum = randint(1, select.length - 1);
251             select.selectedIndex = rnnum;
252         }
253 
254         this.singleSlider = function(subject) {
255 
256             /**
257              *
258              * @param {int} _value 随机值
259              * @param {*} min 可选的最小值
260              * @param {*} max 可选的最大值
261              * @param {*} subject 题目
262              * @description 里面的_coordsX, _Number, getElCoordinate, 方法不用管,这是根据网页的方法复制下来的, 用来反模拟出clientX的值(即鼠标的值), 因为网页上没有提供js直接修改的value,因此只能模拟鼠标时间来点击拉条,需要参数clientX。
263              *
264              */
265             function getClientX(_value, min, max, subject) {
266                 var _bar = subject.querySelectorAll(".imageBar1")[0];
267                 var _slider = subject.querySelectorAll(".imageSlider1")[0]
268 
269                 function _coordsX(x) {
270                     x = _Number(x);
271                     x = x <= _slider.offsetLeft ? _slider.offsetLeft : x >= _slider.offsetLeft + _slider.offsetWidth - _bar.offsetWidth ? _slider.offsetLeft + _slider.offsetWidth - _bar.offsetWidth : x;
272                     return x;
273                 }
274 
275                 function _Number(b) {
276                     return isNaN(b) ? 0 : b;
277                 }
278 
279                 function getElCoordinate(h) {
280                     var e = h.offsetLeft;
281                     while (h = h.offsetParent) {
282                         e += h.offsetLeft;
283                     }
284                     return {
285                         left: e,
286                     };
287                 }
288 
289                 var x = (_value - min) * ((_slider.offsetWidth - _bar.offsetWidth) / (max - min));
290                 x = _coordsX(x);
291                 var clientX = x + getElCoordinate(_slider).left + (_bar.offsetWidth / 2);
292                 return Math.round(clientX);
293             }
294 
295             var max = Number(subject.querySelectorAll(".slider")[0].getAttribute("maxvalue"));
296             var min = Number(subject.querySelectorAll(".slider")[0].getAttribute("minvalue"));
297             //模拟鼠标点击的事件, 关键参数ClientX
298             var evt = new MouseEvent("click", {
299                 clientX: getClientX(randint(min, max), min, max, subject),
300                 type: "click",
301                 __proto__: MouseEvent,
302             });
303             subject.querySelectorAll(".ruler")[0].dispatchEvent(evt);
304         }
305         this.singleStar = function(subject) {
306             var list = subject.querySelectorAll("li:not([class=\'notchoice\'])");
307             list[randint(0, list.length - 1)].click();
308         }
309     }
310 
311 
312     /**
313      * @name 智慧树题目类型判断,并随机选择
314      */
315     function judgeType() {
316         //q = $$(".div_question");
317         var q = document.getElementsByClassName("div_question");
318         var rc = new RandomChoose();
319         for (var i = 0; i < q.length; i++) {
320             //普通单选 or 多选
321             if ((q[i].querySelectorAll(".ulradiocheck")[0]) && (q[i].querySelectorAll("input")[0])) { // 非表格单选或者多选
322                 var input = q[i].querySelectorAll("input");
323                 if (input[0].type == \'radio\') {
324                     console.log("单选题", i);
325                     rc.singleChoose(q[i]);
326                 } else if (input[0].type == \'checkbox\') {
327                     console.log("多选题", i);
328                     rc.multiChoose(q[i]);
329                 }
330 
331                 //表格
332             } else if (q[i].querySelectorAll("table")[0]) {
333                 if (q[i].querySelectorAll("input")[0]) { // 表格题中包含有单选, 多选
334                     input = q[i].querySelectorAll("input");
335                     if (input[0].type == \'radio\') {
336                         console.log("表格单选", i);
337                         rc.martixSingleChoose(q[i]);
338                     } else if (input[0].type == \'checkbox\') {
339                         console.log("表格多选", i);
340                         rc.martixMultiChoose(q[i]);
341                     }
342                 } else if (!q[i].querySelectorAll("input")[0] && q[i].querySelectorAll("li")[0]) { // 表格中的星星题目,没有Input标签
343                     console.log("Martix-Star", i);
344                     rc.martixStar(q[i]);
345                 }
346                 // 填空题
347             } else if (q[i].querySelectorAll("textarea")[0]) {
348                 for(var j = 0; j < config.length; j++){
349                     if(q[i].querySelectorAll("textarea")[0].id == ("q" + config[j].id)){
350                         q[i].querySelectorAll("textarea")[0].value = config[j].answer[Math.floor(Math.random()*config[j].answer.length)];
351                     }
352                 }
353 
354                 console.log("填空", i);
355             } else if (q[i].querySelectorAll(".slider")[0]) {
356                 console.log("Slider-Single-line", i);
357                 rc.singleSlider(q[i]);
358             } else if (q[i].querySelectorAll(".notchoice")[0]) {
359                 console.log("Star-Single-line", i);
360                 rc.singleStar(q[i]);
361             } else if (q[i].querySelectorAll(".lisort")[0]) {
362                 console.log("li-Sort", i);
363                 rc.randomSort(q[i]);
364             } else if (q[i].querySelectorAll("select")[0]) {
365                 console.log("Select", i);
366                 rc.dropdownSelect(q[i]);
367             }
368         }
369         try{
370             var textArea = document.getElementsByTagName(\'textarea\');
371             //textArea[0].value = "无";
372             //textArea[1].value = "无";
373         }catch(error){}
374     }
375     judgeType();
376 
377     //滚动到提交按钮处
378     try {
379         var scrollvalue = document.getElementById("submit_button").offsetParent.offsetParent.offsetTop;
380         window.scrollTo({
381             top: scrollvalue,
382             behavior: "smooth"
383         });
384     } catch (error) {}
385 
386 })();
387 window.alert = function(str) {
388    location.reload();
389    return ;
390 }
391 setTimeout(function(){
392     // 延时两秒防止验证
393     document.getElementById("submit_button").click();
394     console.log("答题成功!");
395 },2000);
396 setTimeout(function(){
397     // 5秒自动刷新,解决验证问题
398     location.reload();
399 },5000);