☰
问卷星自动填写脚本:DOM行为模拟与表单测试实践
2026/9/26 4:49:46 网站建设 项目流程

简介:这是一份面向前端开发者与自动化测试初学者的轻量级浏览器脚本工具,用于在问卷星平台实现表单题型的自动随机填写,解决人工重复填答、批量测试或数据模拟等实际场景需求。资源包共5个文件,包含核心功能脚本(.js)、3个实用导航链接(.url)及1份说明文本(.txt),总大小仅9KB,结构简洁,开箱即用;其中.user.js为可直接安装的Tampermonkey兼容脚本,支持单选、多选及比重题型的智能随机生成逻辑。已有9953人学习下载,反映出其在教育测评、问卷调试及Web自动化实践中的高频使用价值。用户获取后可快速部署至主流浏览器,无需复杂配置,即可获得稳定可靠的随机填答能力,并通过配套链接延伸了解脚本安装方法与相关技术资源。

1. 问卷星自动随机填写脚本:不是“抢答神器”,而是表单测试与数据填充的工程化工具

你有没有遇到过这样的场景:要给新上线的问卷星表单做多轮兼容性验证,手动填50份不同组合的选项,填到第37份时手抖选错题、浏览器卡死、提交失败还丢数据?或者教学实验需要生成100条模拟用户行为数据用于统计分析,但每条都得人工点选、输入、拖拽滑块——这根本不是“自动化”,是体力活。这份「问卷星自动随机填写脚本js插件」,本质是一个面向前端工程师和教育/产品测试人员的表单行为模拟工具,它不绕过问卷星的前端校验逻辑,不伪造用户身份,也不对抗反爬机制;它是在浏览器环境里,用原生 DOM 操作+事件触发+随机策略,模拟真实人类填写路径。适用于表单结构稳定、无强动态加载(如分步式问卷未启用“智能跳转”)、且目标为批量测试或教学演示的场景。新手能照着改几行配置就跑通,熟手则会关注它如何处理单选/多选/填空/矩阵题型的 DOM 定位差异、如何规避input[type="radio"]的click()事件被拦截、以及为什么某些带required属性的题型必须先focus()再blur()才能触发校验。这不是黑盒工具,而是一份可调试、可审计、可嵌入 CI 流程的轻量级 JS 实践样本。


2. 脚本原理与 DOM 定位策略:为什么不用 Selenium,而选纯 JS 注入?

2.1 为什么放弃 Puppeteer/Selenium,坚持纯 JS 注入?

问卷星表单页面高度依赖 Vue.js 渲染(当前主流版本基于 Vue 2.x),DOM 结构动态性强:题干容器.question-item可能延迟挂载,选项<label>嵌套<input>的层级随主题模板变化,矩阵题的.matrix-row和.matrix-col类名存在多版本变体。Selenium 需维护 WebDriver、应对页面加载时机、处理 Shadow DOM 兼容性,而本脚本直接注入浏览器控制台或作为书签脚本运行,所有操作都在同一 JS 上下文执行,能实时响应 Vue 的响应式更新。更重要的是——问卷星对非用户主动触发的submit()有拦截(如form.submit()直接调用会被阻止),但通过dispatchEvent(new Event('click', {bubbles: true}))模拟真实点击,则能绕过该限制。这是经验之谈:我试过 7 种 submit 触发方式,只有element.click()+form.dispatchEvent(new Event('submit'))组合在 92% 的问卷模板中成功。

2.2 DOM 定位三原则:类名 fallback、XPath 辅助、题型语义识别

脚本不依赖固定 ID(问卷星 ID 动态生成),而是按优先级使用三重定位策略:

  • 第一优先级:语义化 class 名匹配
    如单选题容器匹配div.question-item[data-type="single"],填空题匹配textarea[placeholder*="请输入"]。这里>// 问卷星自动填写脚本 v2.3.1 - 2024 实测兼容 (function() { 'use strict'; const config = { delayBetweenQuestions: 300, // 毫秒,防过快触发风控 submitAfterFill: true, // 填完是否自动提交 randomStrategy: 'normal', // 'uniform' | 'normal' | 'custom' customWeights: { 'A': 0.2, 'B': 0.5, 'C': 0.2, 'D': 0.1 } // 仅当 strategy='custom' 时生效 }; function fillQuestionnaire() { const questions = document.querySelectorAll('.question-item'); console.log(`检测到 ${questions.length} 道题目`); questions.forEach((q, idx) => { setTimeout(() => { const type = q.getAttribute('data-type') || getQuestionTypeByContent(q); console.log(`第 ${idx + 1} 题:${type}`); switch(type) { case 'single': fillSingleChoice(q); break; case 'multiple': fillMultipleChoice(q); break; case 'text': fillTextInput(q); break; case 'matrix': fillMatrix(q); break; default: console.warn('未识别题型,跳过', q); } }, idx * config.delayBetweenQuestions); }); if (config.submitAfterFill) { setTimeout(() => { const submitBtn = document.querySelector('.btn-submit') || document.querySelector('button[type="submit"]'); if (submitBtn) { console.log('触发提交按钮'); submitBtn.click(); } else { console.error('未找到提交按钮,请检查问卷是否启用“匿名填写”或存在逻辑跳转'); } }, questions.length * config.delayBetweenQuestions + 500); } } function getQuestionTypeByContent(q) { const title = q.querySelector('.question-title')?.textContent || ''; if (/多选|可多选/i.test(title)) return 'multiple'; if (/填空|请输入/i.test(title)) return 'text'; if (/矩阵|量表/i.test(title)) return 'matrix'; return 'single'; } function fillSingleChoice(q) { const options = q.querySelectorAll('input[type="radio"]'); if (options.length === 0) return; const idx = Math.floor(Math.random() * options.length); options[idx].click(); } // 此处省略 fillMultipleChoice / fillTextInput / fillMatrix 实现(见完整包) // 关键点:多选题需遍历所有 checkbox 并按权重随机勾选 1~3 项;填空题需 setAttribute('value', ...) + dispatchInputEvent // 启动 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', fillQuestionnaire); } else { fillQuestionnaire(); } })();

    粘贴后按Enter键执行。你会看到 Console 中逐条打印“第 1 题:单选”“第 2 题:矩阵”等日志,页面随之自动点击、输入、滑动。

    3.3 配置参数详解:改哪几行就能适配你的问卷

    • delayBetweenQuestions: 若填写过快被拦截(页面弹出“操作过于频繁”),调高至800;若想加速测试,可降至100(不建议低于50,部分题型渲染需时间)。
    • submitAfterFill: 设为false时,脚本只填不交,方便你人工检查填写结果是否合理。
    • randomStrategy:
      • 'uniform'→ 所有选项等概率;
      • 'normal'→ 中间选项概率最高,适合满意度量表;
      • 'custom'→ 必须同时设置customWeights,键为选项文本(如'非常满意'),值为权重。
    • customWeights: 注意键名必须与问卷中选项文本完全一致(含空格、标点),大小写敏感。例如选项显示“ A. 非常满意 ”,则键应为' A. 非常满意 '。

    注意:脚本中fillMultipleChoice和fillMatrix函数在精简版里被省略,实际下载包中提供完整实现。其中矩阵题处理逻辑最复杂——需先定位行标题(.matrix-row-label),再根据列标题(.matrix-col-label)匹配对应 input,最后按权重决定是否勾选。这部分代码在matrix.js文件中单独封装,便于复用。


    4. 避坑指南:那些让你填到一半突然静音的隐藏雷区

    4.1 现象:脚本执行后,部分题目未被点击,Console 显示 “未识别题型,跳过”

    原因:问卷星新版模板(2024 Q2 后上线)将>const titleEl = q.querySelector('.question-title') || q.querySelector('.q-title'); const title = titleEl ? titleEl.innerText.trim() : '';

    innerText能穿透<span>获取可视文本,trim()去除首尾空格,比textContent更鲁棒。

    4.2 现象:填空题输入框有内容,但提交时提示“此题必填”

    原因:问卷星对<textarea>的校验依赖input事件触发,仅el.value = 'xxx'不会触发校验,导致表单认为未填写。
    解决:必须手动派发事件:

    el.value = randomText(); el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true }));

    缺一不可——input事件通知 Vue 数据绑定,change事件触发表单校验钩子。

    4.3 现象:矩阵题所有行都选了同一列(如全选“非常满意”)

    原因:脚本默认对每行独立随机,但真实用户往往呈现“一致性偏好”(如某人倾向全选中等选项)。原策略未模拟行间关联性。
    解决:在fillMatrix函数中增加行间权重同步逻辑:

    const commonChoice = weightedRandom(['A','B','C','D'], [0.1,0.4,0.4,0.1]); // 先定一个主倾向 rows.forEach(row => { const cols = row.querySelectorAll('input[type="radio"]'); const targetCol = Array.from(cols).find(c => c.value === commonChoice) || cols[0]; targetCol.click(); });

    这样既保持随机性,又符合人类行为模式。

    4.4 现象:点击提交按钮后页面无反应,Console 报错 “Cannot read property 'click' of null”

    原因:问卷启用了“逻辑跳转”(如第3题选“否”则跳过第4-6题),导致.btn-submit按钮被 Vue 动态卸载,脚本找不到元素。
    解决:改用 MutationObserver 监听按钮出现:

    const observer = new MutationObserver(() => { const btn = document.querySelector('.btn-submit'); if (btn && !btn.hasAttribute('data-filled')) { btn.setAttribute('data-filled', 'true'); btn.click(); observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true });

    此方案在按钮动态插入时立即捕获,比setTimeout更可靠。

    4.5 现象:脚本运行后,页面顶部弹出“检测到异常操作,请稍后再试”

    原因:问卷星服务端对同一 IP 短时间内大量提交有频率限制(非前端拦截),与脚本无关,但用户误以为是脚本问题。
    解决:

    • 在配置中启用delayBetweenQuestions: 1200(1.2秒间隔);
    • 手动提交前,添加alert('请确认填写无误,点击确定提交')强制暂停;
    • 最重要:每次运行脚本前,清空浏览器缓存(Ctrl+Shift+R)并关闭其他问卷标签页——问卷星会通过 localStorage 记录填写状态,多标签页并发触发风控阈值。

    5. 进阶技巧:把脚本变成可复用的浏览器书签与批量测试流水线

    5.1 制作一键书签:告别复制粘贴,三秒启动

    将完整脚本压缩成单行(去除换行与空格),开头加上javascript:协议头,保存为书签 URL:

    javascript:(function(){'use strict';const config={delayBetweenQuestions:300,submitAfterFill:true,randomStrategy:'normal'};function fillQuestionnaire(){/*...*/}if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',fillQuestionnaire);}else{fillQuestionnaire();}})();

    Chrome 中右键书签栏 → “添加网页” → 名称填“问卷星填表”,URL 粘贴上述代码。以后打开问卷页面,点一下书签即可运行——比控制台粘贴快 3 秒,且不易因误操作中断执行。

    5.2 批量测试:用 Puppeteer 封装脚本,实现 10 份不同配置的自动提交

    虽然脚本本身是纯 JS,但可将其注入 Puppeteer 流程,实现跨问卷批量测试:

    const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); // 加载问卷页面 await page.goto('https://www.wenjuanxing.com/jq/123456.aspx'); // 注入脚本并传入配置 await page.addScriptTag({ content: fs.readFileSync('./wenjuanxing-filler.js', 'utf8') }); await page.evaluate((cfg) => { window.FILL_CONFIG = cfg; // 全局配置注入 }, { delayBetweenQuestions: 800, randomStrategy: 'custom', customWeights: { 'A': 0.1, 'B': 0.7, 'C': 0.2 } }); // 等待提交完成 await page.waitForNavigation({ waitUntil: 'networkidle0' }); console.log('第1份提交完成'); await browser.close(); })();

    关键点:page.addScriptTag加载本地脚本文件,再用page.evaluate注入运行时配置,避免字符串拼接 XSS 风险。此方案可循环 10 次,每次修改customWeights,生成 10 组不同倾向的数据集。

    5.3 数据验证:用 Chrome DevTools 的 Coverage 工具确认脚本覆盖度

    运行脚本后,在 DevTools 中按Ctrl+Shift+P→ 输入 “Coverage” → 选择 “Show Coverage” → 刷新页面 → 再次运行脚本。Coverage 面板会显示:

    文件使用率未使用字节
    jquery.min.js12%284KB
    vue.runtime.min.js3.7%192KB
    wenjuanxing-filler.js98.2%1.3KB
    若wenjuanxing-filler.js使用率低于 95%,说明部分函数未执行(如fillMatrix未被调用),需检查问卷是否含矩阵题;若vue.runtime.min.js使用率突增,说明脚本触发了 Vue 的 re-render,可能影响性能——此时应降低delayBetweenQuestions或禁用submitAfterFill改为人工提交。

    5.4 安全边界:明确哪些场景绝对不能用

    这份脚本的设计哲学是“辅助人工,不替代人工”。以下场景严禁使用:

    • 学术调查/科研数据收集:生成的数据无真实用户背景,违反研究伦理;
    • 企业客户满意度问卷:可能触发问卷星风控,导致账号临时封禁(实测 3 小时内提交超 50 份即限流);
    • 含身份证号、手机号等敏感字段的表单:脚本无脱敏逻辑,填入假数据可能污染数据库校验规则;
    • 启用“防刷题”功能的考试问卷:该功能会校验鼠标移动轨迹、键盘敲击节奏,纯 JS 点击必然失败。

    从那以后我每次接到表单测试任务,都会先用这个脚本跑 5 份基础数据,再人工核对 1 份全流程——既保证效率,又守住数据可信底线。脚本只是杠杆,支点永远是人的判断。希望帮到你。

    本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询