手把手教你写一个简单的油猴脚本:以实验室安全考试自动答题为例

手把手教你写一个简单的油猴脚本:以实验室安全考试自动答题为例 从零构建油猴脚本浏览器自动化实战指南打开开发者工具时你是否好奇过那些能自动填写表单、批量下载资源的神秘代码Tampermonkey油猴作为浏览器脚本的瑞士军刀让普通用户也能用几行JavaScript实现网页操控魔法。本文将以模拟考试系统自动答题为案例带你从零编写第一个实用脚本理解DOM操作与事件模拟的核心逻辑。1. 油猴脚本开发环境搭建在编写第一个.user.js文件前需要完成基础环境配置。推荐使用Chromium内核浏览器如Edge、Chrome或Firefox它们对Tampermonkey扩展的支持最为完善。安装步骤分解访问Tampermonkey官网获取对应浏览器的扩展点击扩展图标 → 创建新脚本进入编辑器界面观察自动生成的脚本模板结构注意部分企业网络可能限制扩展安装个人开发建议使用常规网络环境基础脚本模板包含关键元数据区块例如// UserScript // name My First Script // namespace http://tampermonkey.net/ // version 0.1 // description try to take over the world! // author You // match https://www.example.com/* // grant none // /UserScript其中match参数决定了脚本的生效范围支持通配符匹配*://*.example.com/*匹配所有协议的子域名路径https://example.com/user/*精确匹配特定路径2. 网页元素定位技术解析实现自动答题的第一步是准确获取题目元素。现代网页主要采用CSS选择器或XPath定位DOM节点油猴脚本通常使用浏览器原生API// 获取所有class包含question的div元素 const questions document.querySelectorAll(div.question); // 通过XPath查找包含选择题文本的节点 const xpathResult document.evaluate( //*[contains(text(),选择题)], document, null, XPathResult.ANY_TYPE, null );元素定位实战技巧使用开发者工具(Console)测试选择器有效性优先选择具有唯一性的id或data-*属性对于动态加载内容需配合MutationObserver监听DOM变化下表对比常见定位方法方法优点缺点getElementById性能最佳仅适用于唯一IDquerySelector支持CSS3复杂选择返回首个匹配项getElementsByClassName批量获取同类元素返回动态HTMLCollectionXPath支持文本内容定位语法复杂3. 自动答题核心逻辑实现基于实验室考试系统的特点我们需要构建题目识别→答案匹配→自动填充的完整流程。以下是简化版实现框架function autoAnswer() { // 1. 题目采集 const questionElements document.querySelectorAll(.shiti); const questionBank { 实验室灭火器类型: 干粉灭火器, 酸碱中和原则: 酸入水 }; // 2. 答案匹配 questionElements.forEach(q { const text q.textContent.trim(); const matchedAnswer questionBank[text]; // 3. 自动填充 if (matchedAnswer) { const options q.querySelectorAll(input[typeradio]); options.forEach(opt { if (opt.nextSibling.textContent.includes(matchedAnswer)) { opt.click(); } }); } }); } // 页面加载完成后执行 window.addEventListener(load, autoAnswer);关键点优化建议使用textContent而非innerHTML避免XSS风险添加setTimeout延迟确保动态内容加载完成对题目文本进行模糊匹配如去除标点、空格4. 脚本健壮性增强策略生产环境脚本需要考虑异常处理和兼容性。以下是提升可靠性的实践方案// 错误边界处理 try { const unsafeOperation () { /*...*/ }; unsafeOperation(); } catch (e) { console.error(脚本执行失败: ${e.message}); // 优雅降级方案 alert(自动答题功能暂不可用请手动作答); } // 多版本兼容检测 if (typeof Promise ! undefined) { // 现代浏览器逻辑 } else { // 传统浏览器备用逻辑 }健壮性检查清单[ ] 添加网络请求超时限制[ ] 处理iframe嵌套页面场景[ ] 验证DOM元素存在性再操作[ ] 提供用户关闭自动化的选项5. 高级技巧题库外部化与更新机制硬编码题库不利于维护可通过外部资源实现动态加载const loadQuestionBank async () { const response await fetch(https://example.com/api/questions); return response.json(); }; // 配合GM_xmlhttpRequest使用需声明grant GM_xmlhttpRequest({ method: GET, url: https://example.com/data.json, onload: function(response) { console.log(题库加载完成, JSON.parse(response.responseText)); } });版本控制方案对比方案实现难度可维护性实时性脚本内嵌题库★☆☆☆☆★★☆☆☆★☆☆☆☆JSONP接口调用★★★☆☆★★★★☆★★★★☆GitHub RAW托管★★☆☆☆★★★★☆★★★☆☆用户本地存储★★★☆☆★★☆☆☆★☆☆☆☆在开发者工具的Network面板中我经常发现某些API请求返回的题库数据格式与预期不符。这时需要添加类型校验function validateQuestion(data) { return Array.isArray(data) data.every(item typeof item.question string Array.isArray(item.answers) ); }掌握这些技巧后你可以进一步探索与浏览器存储(localStorage)结合实现用户配置持久化添加可视化控制面板(GM_registerMenuCommand)开发跨站点通用答题框架