问卷星在线刷

问卷星在线批量刷,自动答题,自动刷新(清除)Cookies,需手动点击滑块验证和提交,支持单选、多选、下拉框、量表、矩阵量表、填空。代码采用ES6+,低版本浏览器可能无法使用。不需要更改链接中的 vm 为 vj。

// ==UserScript==
// @name         问卷星在线刷
// @namespace    http://tampermonkey.net/
// @version      1.0.4
// @description  问卷星在线批量刷,自动答题,自动刷新(清除)Cookies,需手动点击滑块验证和提交,支持单选、多选、下拉框、量表、矩阵量表、填空。代码采用ES6+,低版本浏览器可能无法使用。不需要更改链接中的 vm 为 vj。
// @author       ZZY
// @match        https://www.wjx.cn/*
// @icon         https://www.wjx.cn/favicon.ico
// @license      MIT
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // ---------- 初始化 ----------
    // 清除缓存
    window.localStorage.clear()
    window.sessionStorage.clear()
    clearCookies()

    // 定义自己问卷的 url
    const url = 'https://www.wjx.cn/vm/ODYlfUQ.aspx'

    // 重定向页面
    if (window.location.href.indexOf('https://www.wjx.cn/wjx/join') !== -1) {
        setTimeout(() => {
            window.location.href = url
        }, 200)
    }

    // 平滑滚动到页面低端
    window.scrollTo({
        top: document.body.scrollHeight, left: 0, behavior: 'smooth'
    })

    // ---------- 定义参数 ----------
    let list = []
    let questionList = document.getElementsByClassName('field ui-field-contain')
    let answerList = [
        {id: 1, type: '单选', bili: [30, 70]},
        {id: 2, type: '单选', bili: [20, 30, 30, 20]},
        {id: 3, type: '多选', bili: [50, 50, 50, 50]},
        {id: 4, type: '多选', bili: [20, 30, 30, 30, 40]},
        {id: 5, type: '下拉', bili: [20, 30, 40, 10]},
        {id: 6, type: '下拉', bili: [30, 20, 10, 40]},
        {id: 7, type: '量表', bili: [25, 25, 25, 25]},
        {id: 8, type: '量表', bili: [20, 20, 20, 20, 20]},
        {id: 9, type: '填空', bili: [50, 50], content: ['哈哈哈', '嘿嘿嘿']},
        {id: 10, type: '填空', bili: [50, 50], content: ['哈哈哈', '嘿嘿嘿']},
        {id: 11, type: '矩阵量表', bili: [[20, 20, 20, 20, 20], [10, 20, 40, 20, 10]]}
    ]

    // ---------- 问卷答题逻辑 ----------
    for (let i = 0; i < questionList.length; i++) {
        list.push(questionList[i].children[1])
    }

    for (let i = 0; i < list.length; i++) {
        let type = answerList[i].type // 获取当前问题的类型
        switch (type) {
            case '单选': {
                list[i].children[radio(answerList[i].bili)].click()
                break
            }
            case '多选': {
                let flag = true
                while (flag) {
                    for (let j = 0; j < answerList[i].bili.length; j++) {
                        if (check(answerList[i].bili[j])) {
                            list[i].children[j].click()
                            flag = false
                        }
                    }
                }
                break
            }
            case '下拉': {
                list[i].children[0].children[0].children[radio([0, ...answerList[i].bili])].selected = true
                break
            }
            case '量表': {
                list[i].children[0].children[1].children[radio(answerList[i].bili)].click()
                break
            }
            case '矩阵量表': {
                for (let j = 0; j < answerList[i].bili.length; j++) {
                    list[i].children[0].children[1].children[(j+1)*2].children[radio((answerList[i].bili[j]))+1].click()
                }
                break
            }
            case '填空': {
                list[i].children[0].value = answerList[i].content[radio(answerList[i].bili)]
                break
            }
            default:
                break
        }
    }

    console.log('navigator:',window.navigator)

    // 提交
    let count = 0
    setTimeout(() => {
        console.log('navigator:', window.navigator)
        document.getElementById('ctlNext').click()
        setTimeout(() => {
            document.getElementsByClassName('layui-layer-btn0')[0]?.click()
            document.getElementById('SM_BTN_1').click()
            // setInterval(() => {
            //     try {
            //         slidingSlider()
            //         count += 1
            //     } catch (err) {
            //         if (count >= 5) {
            //             window.location.reload()
            //         }
            //     }
            // }, 500)
        }, 1000)
    }, 1000)

    // ---------- 函数 ----------

    // 单选题执行逻辑
    function radio(bili) {
        let flagNum = randomNum(1, 100)
        for (let i = 0; i < bili.length; i++) {
            let startNum = i === 0 ? 0 : accumulation(bili, i)
            let endNum = accumulation(bili, i + 1)
            if (isInRange(flagNum, startNum, endNum)) return i
        }
    }

    // 多选题执行逻辑
    function check(probability) {
        let flagNum = randomNum(1, 100)
        return isInRange(flagNum, 1, probability)
    }

    // 生成从 minNum 到 maxNum 范围的函数
    function randomNum(minNum = 1, maxNum) {
        return Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum
    }

    // 累加
    function accumulation(list, num) {
        let sum = 0
        for (let i = 0; i < num; i++) {
            sum += list[i]
        }
        return sum
    }

    // 判断 num 是否在区间内
    function isInRange(num, startNum, endNum) {
        return num >= startNum && num <= endNum;

    }

    // 清除 cookies 函数
    function clearCookies() {
        document.cookie.split(';').forEach(cookie => {
            const [name, ...parts] = cookie.split(/=(.*)/);
            const value = parts.join('=');
            const decodedName = decodeURIComponent(name.trim());
            const decodedValue = decodeURIComponent(value.trim());
            document.cookie = `${decodedName}=${decodedValue}; expires=Thu, 01 Jan 1970 00:00:00 UTC;`;
        });
    }

    // 滑动滑块来验证
    function slidingSlider() {
        const slider = document.querySelector("#nc_1_n1z");
        const startX = slider.getBoundingClientRect().left + window.pageXOffset;
        const startY = slider.getBoundingClientRect().top + window.pageYOffset;
        const endX = startX + 260;
        const endY = startY;
        const options = {bubbles: true, cancelable: true};

        slider.dispatchEvent(new MouseEvent('mousedown', options));
        slider.dispatchEvent(new MouseEvent('mousemove', Object.assign(options, {clientX: startX, clientY: startY})));
        slider.dispatchEvent(new MouseEvent('mousemove', Object.assign(options, {clientX: endX, clientY: endY})));
        slider.dispatchEvent(new MouseEvent('mouseup', options));

    }
})();