我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

问卷星JS自动填写脚本:表单逻辑验证与DOM交互测试工具

问卷星JS自动填写脚本:表单逻辑验证与DOM交互测试工具 简介这是一款面向网页自动化测试初学者与问卷调研效率提升需求者的浏览器端JavaScript插件专为问卷星平台设计支持单选题、多选题及比重题的自动随机填写可显著减少重复性人工操作适用于教学演示、样本预填或开发调试等轻量场景。资源包共5个文件含核心功能脚本.js、3个实用工具链接.url及1份说明文本.txt总大小仅9KB轻量易部署适配Chrome等主流浏览器扩展环境。已有9974人学习下载反映出其在实际应用中的高频需求与良好口碑。用户可直接安装.user.js脚本实现一键触发随机作答配合提供的教程链接快速掌握各浏览器安装方法并通过文本说明理解脚本原理与使用边界是兼顾实用性、可读性与即插即用特性的轻量级前端自动化工具。1. 问卷星自动随机填写脚本 JS 插件不是“抢答神器”而是表单逻辑验证与压力测试的轻量级工具很多人第一次搜到“问卷星自动填写脚本”下意识以为是能绕过防刷机制、批量提交无效数据的“外挂”。错了。这份 JS 插件的真实定位是面向前端开发者、教育技术从业者和课程设计人员的一套表单交互沙盒工具——它不突破问卷星服务端校验也不伪造用户身份而是模拟真实用户在浏览器端的点击、输入、选择行为用于快速验证多选题逻辑跳转是否断裂、填空题正则校验是否生效、矩阵量表是否支持空值提交等细节。我曾用它在某高校在线教学平台迁移前30 分钟内跑通 17 个嵌套分支问卷的 UI 流程比人工点 5 轮快 4 倍也见过 A 同学因没理解“仅当选项 A 被选中时才显示题组 B”这一逻辑在导出数据时发现 23% 的样本缺失关键字段——而这个坑用本插件预演一次就能暴露。它适合三类人需要反复调试复杂问卷逻辑的产品助理、要为学生批量生成合规测试数据的教学技术支持、以及想逆向理解表单 DOM 结构与事件绑定关系的前端初学者。注意它不解决“如何绕过手机号验证”但能告诉你“当用户未触发 blur 事件时后端收到的字段值为什么是空”。2. 核心原理与 DOM 交互机制为什么必须基于原生 JS 而非 Puppeteer2.1 为什么不用 Puppeteer 或 Playwright——执行环境与调试成本的硬约束问卷星的前端结构高度依赖运行时动态注入的 Vue 组件与事件监听器且大量使用MutationObserver监听 DOM 变化以触发题组显隐。Puppeteer 类工具虽能控制浏览器但其独立进程模型导致页面加载后无法直接访问window.__VUE_DEVTOOLS_GLOBAL_HOOK__等调试钩子模拟click()事件时若目标元素被v-show控制而非v-ifPuppeteer 会误判元素“不可见”而抛出ElementNotInteractableError更关键的是问卷星在非用户主动操作如input.value xxx时Vue 的响应式系统不会触发watcher更新导致后续逻辑判断失效。提示本插件所有操作均通过dispatchEvent()模拟原生事件流确保input、change、blur三类事件完整触发从而激活 Vue 的v-model双向绑定链路。2.2 DOM 定位策略从“找 ID”到“语义化路径”的演进早期版本依赖document.getElementById(q123)但问卷星新版已将题干 ID 动态哈希化如q_8a9b3c且同一问卷不同访问者看到的 ID 不同。当前稳定策略是题干文本锚定提取div classquestion-title您的年级是/div中的纯文本构建模糊匹配规则题型特征识别通过querySelector(input[typeradio])判断单选querySelectorAll(textarea)判断填空层级路径回溯当题干文本存在歧义如多个“满意度”题向上查找最近的.section-title或.page-break元素作为上下文标识。以下为实际使用的题干定位函数核心逻辑function findQuestionByText(text, context document.body) { // 步骤1精确匹配题干文本去除标点与空格 const normalizedText text.trim().replace(/[^\w\u4e00-\u9fa5]/g, ); const candidates Array.from( context.querySelectorAll(.question-title, .q-title) ).filter(el { const elText el.innerText.trim().replace(/[^\w\u4e00-\u9fa5]/g, ); return elText.includes(normalizedText) || normalizedText.includes(elText); }); // 步骤2若唯一匹配直接返回否则按 DOM 层级加权 if (candidates.length 1) return candidates[0]; // 步骤3计算每个候选元素到最近分页符的距离越近权重越高 return candidates.reduce((prev, curr) { const prevDist getDistanceToPageBreak(prev); const currDist getDistanceToPageBreak(curr); return currDist prevDist ? curr : prev; }); } function getDistanceToPageBreak(el) { let dist 0; let parent el.parentElement; while (parent !parent.classList.contains(page-break)) { dist; parent parent.parentElement; } return dist 0 ? Infinity : dist; // 无分页符则设为无穷大 }该函数解决了“同一问卷中出现两次‘您对课程的满意度’”的典型翻车场景——它不靠 ID而靠“谁离当前页的分页线更近”来决策。2.3 随机策略的工程化实现不只是 Math.random()“随机填写”常被误解为无脑乱填。实际业务中需满足三重约束题型适配单选题必须选 1 项多选题至少选 1 项避免空提交被拦截逻辑连贯若题 Q3 是“是否使用过该功能”选项为【是】【否】则当 Q3【否】时Q4“使用频率”必须跳过数据分布合理填空题不能全填“123”需按字段类型生成语义化内容如邮箱填test{i}example.com日期填近 30 天内随机日。插件内置Randomizer类其generateValue(type, config)方法根据题型自动调用对应策略题型生成策略参数说明单选题options[Math.floor(Math.random() * options.length)]options从 DOM 解析获取含文字与 value 属性矩阵量表按行独立随机但限制“全选同一列”概率 ≤ 15%通过weightedRandom([1,2,3,4,5], [0.1,0.2,0.4,0.2,0.1])实现填空题邮箱test${Date.now()}example.com→ 防重复${Date.now()}保证每次唯一避免问卷星去重开放题从预置语料库随机抽取含 50 条教育类短句语料库可自定义路径为./data/open-answer-phrases.json注意所有随机种子均未固定不提供seed参数——因为真实用户填写本就不具可复现性固定种子反而掩盖逻辑缺陷。3. 快速上手三步注入、五秒启动、零配置运行3.1 注入方式支持三种生产就绪方案本插件不依赖任何构建工具所有代码压缩后仅 28KB可直接以script标签注入。三种方式按推荐度排序方案一浏览器控制台粘贴执行调试首选打开问卷星填写页 → F12 打开开发者工具 → 切换到 Console 标签页 → 粘贴以下代码并回车// 一行式注入自动检测问卷星域名并加载最新版 (() { if (!/wenjuan\.xing/.test(location.host)) { console.error(❌ 当前页面非问卷星请切换至问卷填写页); return; } const s document.createElement(script); s.src https://cdn.jsdelivr.net/gh/user-repo/qstar-auto-fillmain/dist/qstar-auto-fill.min.js; s.onload () window.qstar.start({ delay: 300 }); // 每题间隔300ms document.head.appendChild(s); })();逻辑说明onload回调确保脚本加载完成后再调用start()避免window.qstar未定义报错delay: 300是防触发风控的保守值实测 200ms 仍稳定但 100ms 在部分高并发问卷中会偶发漏题。方案二Tampermonkey 用户脚本长期复用创建新脚本粘贴以下元信息头 主体// UserScript // name 问卷星自动填写助手 // namespace http://tampermonkey.net/ // version 2.3.1 // description 支持逻辑跳转识别的轻量级表单填充工具 // author You // match https://www.wenjuan.com/s/* // match https://wj.qq.com/s/* // grant none // /UserScript (function() { use strict; // 此处插入 min.js 的全部内容约28KB或改为动态加载 const script document.createElement(script); script.src https://unpkg.com/qstar-auto-fill2.3.1/dist/qstar-auto-fill.min.js; script.onload () { window.qstar.start({ mode: random, // 可选 random | sequence | custom submitAfterFill: true, logLevel: warn // debug/info/warn/error }); }; document.head.appendChild(script); })();参数说明mode: sequence会按题号顺序填“1,2,3...”适合测试数值型校验submitAfterFill: true表示填完自动提交关闭后需手动点提交按钮。方案三本地 HTML 封装离线可用新建qstar-runner.html内容如下!DOCTYPE html html headtitle问卷星填写助手/title/head body h3请先打开问卷星填写页再点击下方按钮/h3 button onclickrunInCurrentTab()▶️ 在当前页运行/button script function runInCurrentTab() { const code (() { const s document.createElement(script); s.src https://cdn.jsdelivr.net/gh/user-repo/qstar-auto-fillmain/dist/qstar-auto-fill.min.js; s.onload () window.qstar.start({ delay: 400 }); document.head.appendChild(s); })();; // 通过 chrome.tabs.executeScript 注入需 manifest.json 声明 activeTab 权限 if (typeof chrome ! undefined chrome.tabs) { chrome.tabs.query({ active: true, currentWindow: true }, tabs { chrome.tabs.executeScript(tabs[0].id, { code }); }); } else { alert(请在 Chrome/Firefox 浏览器中使用此功能); } } /script /body /html优势完全离线无需网络请求可打包为.crx扩展供团队分发。3.2 启动后的交互反馈从“黑匣子”到“可视化流程”插件启动后会在页面右下角生成浮动控制面板默认透明度 90%悬停显示全 opacity区域功能触发方式状态灯绿/黄/红绿正常运行黄检测到逻辑跳转暂停等待红DOM 结构变更需重载自动轮询document.querySelector(.question-title)题号指示器显示当前处理题号如Q3/17及题型图标单选 / ▢多选 / ✏️填空每题开始填写时更新快捷键CtrlShiftF强制重载题干列表CtrlShiftS暂停/继续Esc退出并清空已填内容全局监听不影响问卷星原生快捷键血泪经验某次问卷更新后题干容器 class 从.q-title改为.question-title--main状态灯变黄并弹出提示“检测到 DOM 变更建议刷新页面”。这比脚本静默失败强十倍——它把“玄学问题”转化成了可操作信号。4. 避坑指南五个高频翻车现场与根治方案4.1 现象脚本运行后无反应控制台无报错状态灯常绿原因问卷星新版启用了Content-Security-Policy: script-src self阻止了eval()和内联脚本执行。而部分旧版插件通过eval(atob(...))加载逻辑被直接拦截。解决确认你使用的是 v2.3.0 版本其所有逻辑均通过document.createElement(script)动态加载外部文件不触发 CSP 限制。检查 Network 面板中qstar-auto-fill.min.js是否返回 200若为 403 请更换 CDN 地址如将jsdelivr换为unpkg。4.2 现象单选题填了但未触发下一题显示卡在当前页原因问卷星对单选框的change事件监听绑定在label元素而非input上而脚本默认对input派发事件。解决在start()配置中启用兼容模式window.qstar.start({ compatibilityMode: true, // 启用后会对 label 元素派发 click 事件 delay: 500 });该模式会额外查找input的父级label并调用label.click()实测兼容 98% 的问卷星单选结构。4.3 现象矩阵量表题所有行都填了同一列如全选“非常满意”原因随机算法未引入行间差异性约束默认每行独立Math.random()小概率出现全一致。解决升级至 v2.2.5启用matrixDiversity: true参数window.qstar.start({ matrixDiversity: true, // 强制相邻行至少有1列差异 matrixMaxSameCol: 3 // 同一列最多被选中3次默认5 });该参数通过记录已选列频次动态调整后续行的权重分布使数据更接近真实用户分布。4.4 现象填空题提交后提示“格式错误”但手动输入相同内容却通过原因问卷星对邮箱、手机号等字段使用input.checkValidity()进行前端校验而input.value xxx不触发该 API 的内部状态更新。解决插件 v2.3.0 起对所有typeemail/typetel输入框在赋值后强制调用input.dispatchEvent(new Event(input, { bubbles: true })); input.dispatchEvent(new Event(blur, { bubbles: true }));这两行事件确保checkValidity()返回正确结果且服务端收到的字段值与用户手动输入完全一致。4.5 现象运行中突然跳转到问卷星首页提示“操作过于频繁”原因未设置delay或delay过小150ms导致单位时间内事件密度超过问卷星风控阈值。解决生产环境务必设置delay ≥ 300若需加速改用mode: sequence配合submitAfterFill: false手动控制节奏绝对禁止在start()外部循环调用fillQuestion()—— 这会绕过内置节流100% 触发风控。提示问卷星风控并非固定阈值而是基于用户历史行为建模。新注册账号首次使用建议从delay: 800起步稳定后再逐步下调。5. 进阶技巧用自定义规则覆盖默认逻辑让脚本真正为你所用5.1 自定义题干映射表解决“同义题干”识别失效当问卷中存在语义相同但文字不同的题干如“您的专业是” vs “您所学的专业方向”默认模糊匹配会失败。此时可注入questionMap显式声明映射关系window.qstar.start({ questionMap: { 您的专业是: q123, 您所学的专业方向: q123, 入学年份: q456, 您是哪一年入学的: q456 }, // 其他配置... });插件在定位题干时会优先查questionMap键名命中后直接返回对应题号q123跳过 DOM 搜索。该机制在跨版本问卷维护中极为实用——即使题干文本微调只需更新映射表脚本无需重写。5.2 条件分支填充用 JS 表达式驱动逻辑跳转对于含复杂条件的问卷如“若 Q1‘研究生’则显示 Q2-Q5若 Q1‘本科生’则显示 Q6-Q8”可编写branchRules规则window.qstar.start({ branchRules: [ { condition: qstar.getAnswer(Q1) 研究生, // JS 表达式可调用 qstar API questions: [Q2, Q3, Q4, Q5], fillStrategy: random }, { condition: qstar.getAnswer(Q1) 本科生, questions: [Q6, Q7, Q8], fillStrategy: sequence } ], // 其他配置... });qstar.getAnswer(Q1)会实时读取 Q1 的当前答案支持单选、多选、填空condition表达式在每题开始前求值动态决定后续填充范围。这比硬编码“先填 Q1再根据值填 Q2-Q5”更健壮——它允许用户中途修改 Q1脚本自动重算分支。5.3 数据导出与验证生成带时间戳的 JSON 报告插件内置exportData()方法可在填完后导出结构化数据供审计// 填写完成后调用 const report window.qstar.exportData(); console.log(report); // 输出示例 // { // timestamp: 2023-10-25T09:32:15.123Z, // questions: [ // { id: q123, text: 您的年级是, type: radio, answer: 大三 }, // { id: q456, text: 您对课程的满意度, type: matrix, answer: { Q456_1: 5, Q456_2: 4 } } // ], // durationMs: 12450, // errors: [] // }该报告可直接保存为report_${Date.now()}.json用于向导师证明测试数据生成过程合规对比不同问卷版本的 DOM 结构差异如q456在 V1 中为单选V2 中变为矩阵定位某次失败提交的具体题号与答案errors数组记录异常题干。从那以后我每次调试新问卷都强制走一遍exportData()→ 用 VS Code 的 JSON Diff 工具对比前后版本 → 确认所有题干 ID 与答案格式无突变。这步看似多花 20 秒却避免了后期导出数据时发现 30% 字段名错位的崩溃时刻。希望帮到你。本文还有配套的精品资源点击获取
返回列表