ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

油猴Tampermonkey进阶实战:从API详解到批量自动化任务

油猴Tampermonkey进阶实战:从API详解到批量自动化任务 油猴Tampermonkey可能是浏览器插件里被误解最多的一个。多数人只拿它装别人写好的脚本用来去广告、看视频、下载资源。但如果你只把它当成“脚本安装器”那确实浪费了。它真正的价值是把浏览器变成一个可编程的执行环境拦截请求、改写网页、调用本地接口、跑批量任务、持久化数据、做配置面板全都能在脚本里完成。对经常处理重复性网页操作的人来说油猴不是“开挂插件”是一个轻量级自动化平台。这篇文章不再重复那些被讲烂的脚本推荐而是从技术角度把油猴的隐藏能力拆开讲。内容包括核心能力速览、脚本安装与权限模型、油猴 API 实战GM_config、GM_setValue、GM_xmlhttpRequest、GM_addStyle 等、批量任务设计、服务对接、资源占用与性能注意事项、常见问题排查以及安全合规边界。读完你可以判断油猴到底适不适合接进自己的工作流怎么用才算用对。1. 核心能力速览先把油猴的技术特征列成一个速览表方便快速对号入座。能力项说明项目类型浏览器用户脚本管理器支持 Chrome / Edge / Firefox / Safari / Opera核心功能管理并运行用户脚本UserScript可在页面加载前拦截和改写网页行为脚本来源可从 Greasy Fork 等脚本平台安装也可本地新建脚本或导入 .user.js 文件数据存储GM_setValue / GM_getValue 提供持久化键值存储刷新页面后数据不丢配置面板GM_config 或基于 GM_registerMenuCommand 的自定义配置菜单接口请求GM_xmlhttpRequest 可发跨域请求绕过浏览器页面的 CORS 限制也能带自定义头生命周期可监听 document-start、document-end、document-idle 等运行时机批量任务配合页面 DOM 监听和值存储可实现队列式批量处理运行环境脚本运行在沙箱环境非页面全局 window权限受脚本头部声明控制适用场景自动化操作、数据抓取、接口联调、本地服务对接、效率工具、功能增强安全边界脚本对页面有较高控制权来源不明的脚本存在风险安装前需核对代码从这张表能看出两个重点。第一油猴的表现能力很强几乎能控制页面的全部生命周期。第二油猴的权限完全由脚本头部元数据声明决定安装第三方脚本时一旦给了grant权限脚本就能跨域请求、读取页面内容、操作系统菜单。所以“能干什么”和“该不该被信任”是两件事后面会专门讲权限和安全。2. 适用场景与使用边界2.1 适合什么场景油猴不是万能框架但它在以下几类场景里非常顺手。重复性操作自动化。比如每天登录后台、点击某个按钮、下载同类型文件、填写表单只要操作步骤固定就可以用脚本监听按钮或定时触发把多步操作收敛成一次点击。网页内容增强。常见做法是改样式、加快捷键、加搜索框、加数据统计、合并页面信息。这类脚本基本不涉及跨域复杂度适合新手入门。跨域接口调用。普通网页因为 CORS 限制很难直接请求其他域名接口。油猴的 GM_xmlhttpRequest 绕开浏览器同源策略可以在脚本里请求任意域名再配合 GM_setValue 做缓存。这也是油猴被大量用于数据聚合、信息增强的核心原因。本地服务对接。如果你的电脑上跑着一个本地端口服务比如 OCR 服务、翻译 API、图片处理服务网页脚本可以用 GM_xmlhttpRequest 或 fetch 直接调用本地地址再把结果回填到页面。这样前端不用做任何服务器改造就能实现“页面 本地工具链”的联动。2.2 不擅长什么场景油猴不适合做高并发抓取因为它依赖浏览器页面环境和 JS 事件循环大量异步请求容易把浏览器拖卡。它也不适合当成完整后端服务脚本没有常驻进程页面关闭就停止执行。对于需要严格审计、版本回溯、多人协作的业务逻辑与其写在油猴脚本里不如写进正式项目。2.3 使用边界与合规提醒油猴脚本可以随时读写当前页面的 DOM、Cookie、Storage可以发起任意跨域请求相当于一个高权限客户端。使用者必须确认脚本来源可信尤其是那些带有获取账号信息、读取隐私页面、自动发送请求的脚本。在生产环境使用第三库脚本前先打开脚本源码检查网络请求和存储读写行为。涉及页面上他人数据、版权内容、登录态信息的批量化操作使用时要注意平台规则和授权边界。本地测试可以随便做发布或商用前需要做效果复核避免触发反爬限制或法律风险。3. 环境准备与前置条件3.1 Chrome / Edge 用户准备什么油猴的安装路径很固定不需要配置 PATH、不需要装 Node、不需要装 Python。准备工作主要是确定浏览器版本和新标签页扩展入口。以 Chrome 或 Edge 为例打开扩展管理页地址栏输入chrome://extensions/或edge://extensions/。开启“开发者模式”使本地导入脚本或调试脚本可用。去 Chrome 应用商店或 Edge 加载项商店搜索“Tampermonkey”使用官方图标和发布者信息进行识别。安装完成后固定到扩展栏方便查看当前页面哪些脚本处于活动状态。3.2 Firefox 用户准备什么Firefox 用户可以在附加组件市场中搜索 Tampermonkey。需要注意 Mozilla 对带有特权 API 的扩展审查更严格脚本管理器安装后脚本 API 能力以浏览器版本为准部分敏感 API 在 Firefox 上的行为与 Chrome 略有差异。3.3 端口和本地服务检查如果你要用油猴脚本对接本地服务提前确认目标端口是否被占用。Windows 用户可以用以下命令检查端口状态netstat -ano | findstr :7860如果有进程占用可以换一个端口。你的脚本地址也要随之修改为http://127.0.0.1:7860这样符合本地访问要求的格式。3.4 脚本编辑器准备油猴自带脚本编辑器提供代码高亮和语法折叠。写长脚本的时候建议把代码拆分到本地编辑器里配合 Git 管理版本再粘贴到油猴面板保存。这样做的好处是方便回溯也方便在开发环境和生产环境之间切换。前端开发者可以顺手开启 Chrome DevTools 里的 Sources 面板油猴脚本的沙箱代码会出现在扩展上下文里便于打断点调试。4. 安装部署与脚本启动方式4.1 安装油猴扩展这里给出一个通用安装流程适用于 Chrome / Edge / Firefox 三种主流浏览器。打开浏览器扩展商店搜索“Tampermonkey”。确认发行商避免安装到同名仿冒扩展。点击安装等待浏览器弹出权限确认。安装后点击扩展图标选择“管理面板”或“Create a new script”进入脚本列表。4.2 新建第一个脚本点击油猴图标选择“添加新脚本”后编辑器会自动生成模板。模板头部包含UserScript和/UserScript区块脚本从这里声明运行范围。// UserScript // name Local Demo Script // namespace https://your-domain.example/ // version 1.0.0 // description 演示油猴脚本的配置、存储和菜单能力 // author you // match https://example.com/* // grant GM_registerMenuCommand // grant GM_setValue // grant GM_getValue // grant GM_xmlhttpRequest // run-at document-idle // /UserScript (function () { use strict; console.log(user script started); })();这里简单解释几个字段match声明脚本匹配的网址不匹配的网页不会运行这个脚本。grant声明脚本要使用的油猴增强 API。没声明 GM_xmlhttpRequest 就不能跨域请求。run-at控制运行时机可选document-start、document-body、document-end、document-idle。require可引入外部 JS 库适用场景包括引入 jQuery、Turf.js 等库文件。4.3 脚本的启动与停用脚本安装后不会自动运行只有打开匹配的网页才会生效。点击油猴扩展图标可以看到当前网页匹配了哪些脚本以及每个脚本的开关状态。遇到以下情况时优先检查脚本是否启用而不是脚本代码是否有问题页面没有出现任何期望的变化。控制台没有输出。网络面板没有新增请求。4.4 导入别人的脚本从脚本平台下载.user.js文件后双击或在已安装脚本页面拖入即可导入。导入前先阅读源码确认没有可疑的远程代码加载。5. 功能测试与效果验证5.1 测试环境准备写一个能被油猴拦截的测试页面。建议起一个本地静态服务便于快速修改页面内容观察脚本运行时机。# 本地启动一个静态测试页端口按需调整 cd /path/to/test-page python -m http.server 8080也可以直接找一个没有任何登录鉴权干扰的静态网页做测试目标。5.2 在页面加载时注入样式用 GM_addStyle 向页面注入样式非常适合测试脚本运行时机和 DOM 控制能力。// UserScript // name Style Inject Demo // namespace local.test // version 1.0.0 // match http://127.0.0.1:8080/* // grant GM_addStyle // run-at document-start // /UserScript (function () { use strict; GM_addStyle( .demo-banner { position: fixed; top: 10px; right: 10px; z-index: 999999; background: #1e88e5; color: #fff; padding: 8px 16px; border-radius: 6px; font-size: 14px; font-family: monospace; } ); const banner document.createElement(div); banner.className demo-banner; banner.textContent 油猴脚本注入成功; document.documentElement.appendChild(banner); })();打开测试页后页面右上角如果出现蓝色横幅说明脚本匹配规则、运行时机、DOM 操作都正常。5.3 配置面板与菜单命令脚本如果只是写死逻辑就没办法灵活调整参数。油猴提供了 GM_registerMenuCommand可在扩展菜单里注册命令也可以结合 GM_config 类方法实现可视化配置。以下是注册菜单命令的示例// UserScript // name Menu Command Demo // namespace local.test // version 1.0.0 // match http://127.0.0.1:8080/* // grant GM_registerMenuCommand // grant GM_setValue // grant GM_getValue // /UserScript (function () { use strict; const KEY_ENABLED featureEnabled; function toggleFeature() { const current GM_getValue(KEY_ENABLED, false); GM_setValue(KEY_ENABLED, !current); alert(功能开关已切换为 !current); } GM_registerMenuCommand(切换功能开关, toggleFeature); if (GM_getValue(KEY_ENABLED, false)) { console.log(功能已开启); } })();运行后点击油猴图标会出现“切换功能开关”菜单项。再配合 GM_setValue 就能实现参数持久化刷新页面后不会被重置。5.4 跨域请求测试跨域请求是油猴最实用的能力之一。测试时可以写一个脚本向公开接口发送 GET 请求并把返回内容渲染到测试页。// UserScript // name XHR Demo // namespace local.test // version 1.0.0 // match http://127.0.0.1:8080/* // grant GM_xmlhttpRequest // /UserScript (function () { use strict; GM_xmlhttpRequest({ method: GET, url: https://httpbin.org/get, timeout: 10000, onload: function (response) { console.log(状态码, response.status); console.log(响应内容, response.responseText); }, onerror: function (err) { console.error(请求失败, err); }, ontimeout: function () { console.error(请求超时); } }); })();判断成功的标准很简单控制台出现状态码 200。响应内容完整。浏览器没有抛出 CORS 报错。如果请求失败优先检查域名是否可达、脚本有没有授权 GM_xmlhttpRequest、目标接口是否需要特殊请求头。5.5 POST 请求与表单提交除了 GETGM_xmlhttpRequest 也支持 POST可配合 JSON 数据实现接口联动。GM_xmlhttpRequest({ method: POST, url: https://httpbin.org/post, headers: { Content-Type: application/json }, data: JSON.stringify({ keyword: Tampermonkey, source: local-test }), onload: function (response) { console.log(response.responseText); } });如果目标接口要求带 Cookie可在 headers 里手动添加如果接口要求跟随页面 Cookie也可以用withCredentials: true配合浏览器会话但要注意隐私边界。6. 油猴接口 API 与批量任务设计6.1 常用 API 一览油猴提供了一批增强 API写脚本前先按需声明不要一次性全开。常用 API 如下API作用需要配合的 grantGM_setValue / GM_getValue脚本持久化存储存储简单键值grant GM_setValue等GM_deleteValue删除指定键值grant GM_deleteValueGM_listValues枚举已存值grant GM_listValuesGM_registerMenuCommand注册菜单命令grant GM_registerMenuCommandGM_xmlhttpRequest发起跨域请求grant GM_xmlhttpRequestGM_addStyle注入全局样式grant GM_addStyleGM_openInTab新标签打开地址grant GM_openInTabGM_notification系统级通知grant GM_notification关键点在于只有声明了grant脚本在沙箱环境中才能调用这些 API。若没有写grant脚本的运行模式会偏向普通页面脚本此时直接调用 GM_ 前缀 API 会报未定义。6.2 批量任务状态管理批量任务是油猴脚本经常需要处理的问题。比如批量下载图片、批量导出页面数据、批量提交表单。不要一次性把所有任务全部扔进异步队列浏览器扛不住页面也会崩溃。推荐的做法是设计一个任务队列const queue []; const BATCH_SIZE 3; const INTERVAL_MS 1000; function pushTask(task) { queue.push(task); schedule(); } function schedule() { if (runningCount BATCH_SIZE || queue.length 0) { return; } const task queue.shift(); if (!task) { return; } runningCount 1; executeTask(task) .then(() { console.log(任务完成, task.id); }) .catch((err) { console.error(任务失败, task.id, err); }) .finally(() { runningCount - 1; setTimeout(schedule, INTERVAL_MS); }); }加上GM_setValue后可以把队列状态持久化到本地存储即使页面刷新后也能恢复进度// 保存任务进度 function saveQueueState() { GM_setValue(task_queue, queue.map(function (t) { return { id: t.id, status: t.status }; })); } // 恢复任务进度 function loadQueueState() { return GM_getValue(task_queue, []); }6.3 批量请求的失败重试批量请求遇到超时或 5xx 错误时不建议立即把任务标记为失败。更稳妥的做法是记录重试次数超过阈值才放弃。const MAX_RETRY 3; function executeTask(task) { return new Promise((resolve, reject) { GM_xmlhttpRequest({ method: GET, url: task.url, timeout: 15000, onload: function (res) { if (res.status 400) { return handleRetry(task, reject); } resolve(res.responseText); }, onerror: function () { handleRetry(task, reject); }, ontimeout: function () { handleRetry(task, reject); } }); }); } function handleRetry(task, reject) { task.retryCount task.retryCount || 0; task.retryCount 1; if (task.retryCount MAX_RETRY) { reject(new Error(重试次数达到上限)); return; } queue.push(task); task.status waiting; saveQueueState(); schedule(); }这里顺便说明油猴脚本是单页运行、进程随页面销毁所以批量任务最好设计为可断点续跑。也就是每次任务完成都把状态写进 GM_setValue刷新后优先读取历史状态而不是从头开始。6.4 服务对接示例油猴脚本与本地服务对接时最常见的组合是浏览器脚本监听页面事件把内容发送给http://127.0.0.1:7860的本地推理服务拿到结果后回填到页面。from fastapi import FastAPI app FastAPI() app.post(/process) async def process(item: dict): text item.get(text, ) # 这里可以替换为 OCR / 翻译 / 摘要模型 return {result: processed: text}// 油猴脚本侧发起调用 GM_xmlhttpRequest({ method: POST, url: http://127.0.0.1:7860/process, headers: { Content-Type: application/json }, data: JSON.stringify({ text: 待处理的文本内容 }), onload: function (response) { const json JSON.parse(response.responseText); console.log(本地服务返回, json.result); } });这种设计可以让网页在不依赖后端代理的情况下调用本地算力或本地服务。注意本地端口服务不要绑定0.0.0.0尽量只监听127.0.0.1避免局域网内被其他人访问。7. 资源占用与性能观察7.1 脚本对浏览器的影响油猴本身占用不大真正的性能开销来自脚本逻辑和注入的样式。打开一个页面后可以打开 DevTools 的 Performance 面板观察脚本运行耗时。常见性能问题是run-at document-start的脚本里直接查询 DOM导致页面阻塞时间变长。全局MutationObserver监听整个页面频繁触发回调。批量任务并发太大资源被网络请求占满。脚本反复创建节点页面 DOM 节点数异常增长。7.2 降低占用的方法缩小match匹配范围不要让脚本在所有网站上运行。只在需要的容器上使用MutationObserver不要监听document.body全部变化。把耗时的数据处理放进setTimeout或requestIdleCallback中。批量下载时限制并发数和间隔。不用require加载体积动辄几百 KB 的库优先写原生 JavaScript 完成。7.3 如何观察脚本是否泄漏在 DevTools 的 Memory 面板中多次执行“点击触发任务 - 任务完成”的流程观察堆内存快照是否持续增长。如果多次快照后内存占用明显上升说明脚本存在事件监听或闭包引用泄漏。这时候要检查页面卸载时是否解绑监听器window.addEventListener(beforeunload, function () { observer.disconnect(); // 释放全局引用 window.__myScript null; });8. 常见问题与排查方法下面是油猴使用过程中出现频率较高的问题按“现象 - 原因 - 排查 - 解决”组织成表。问题现象可能原因排查方式解决方案安装后脚本不工作页面 URL 与 match 不匹配点击油猴图标查看脚本匹配列表调整 match 规则到实际页面地址控制台报 GM_xxx is not defined脚本未声明对应的 grant查看脚本编辑器头部元数据补充 grant GM_xxx 后保存请求出现 CORS 报错使用了页面 fetch 而不是 GM_xmlhttpRequest检查请求调用代码改为 GM_xmlhttpRequest 并声明 grant页面加载速度变慢脚本在 document-start 做了大量同步操作Performance 面板定位耗时函数延迟执行或改用 document-idle多脚本冲突多个脚本修改了同一个 DOM 节点逐个禁用脚本定位冲突调整脚本运行顺序或合并功能脚本之间数据互相干扰所有脚本共享 GM 存储命名空间查看 GM_listValues给键名加唯一前缀如appName_批量任务到一半停止页面刷新、脚本运行时机丢失查看存储里的任务队列状态增加队列持久化和恢复逻辑下载文件名乱码服务端响应头无正确编码抓包查看响应头手动解析 Content-Disposition油猴图标变灰当前页面禁止脚本运行检查扩展权限和浏览器模式改用允许的页面或调整 match50 系显卡或新浏览器无法运行脚本浏览器版本过旧扩展 API 不兼容检查扩展更新升级浏览器和 Tampermonkey 到最新版本排错的时候不要一上来就改代码。先确认脚本是否启用再确认匹配规则是否命中最后看控制台报错。多数问题集中在match和grant两个地方。9. 最佳实践与使用建议9.1 脚本命名和存储规范脚本的命名空间和键名前缀要规范。比如写一个翻译增强脚本键名统一使用translate_前缀避免和其他脚本冲突。存储的数据只放必要内容不要存放明文密码。9.2 最小权限原则grant不要一步到位全开。只声明用到的 API。之前看到一个脚本明明只做样式美化却声明了 GM_xmlhttpRequest 和 GM_openInTab这不是技术需要是权限过度扩张需要警惕。9.3 版本管理和备份脚本开发到一定阶段后把头部信息、依赖声明和关键功能写进 README。定期用油猴的导入导出功能备份脚本列表。更新第三方脚本前先对比新旧源码的差异重点关注网络请求地址和 API 调用变化。9.4 如何避免影响正常浏览建议按“站点分组”管理脚本开发环境脚本、生产环境脚本、临时调试脚本分开存放。不需要的脚本及时禁用。如果一个页面同时被多个增强脚本操作切换功能前先禁用无关脚本再做回归测试。9.5 安全与合规提醒最后再强调一次油猴脚本拥有修改页面和发起网络请求的能力等同于在浏览器里安装了一个高权限应用。只有从来源明确、代码可见的地方安装脚本或者自己编写并审计代码才能把风险控制在合理范围内。涉及登录态、Cookie、个人信息、版权内容、他人数据的使用需遵守平台规范和法律规定。本地测试不论发布或商用前要单独评估授权边界并在必要时咨询相关法务。10. 总结与下一步油猴最值得尝试的一点是它能让你绕过“改服务端”这个重活直接在浏览器这一层解决 80% 的页面增强需求。第一次上手可以先从两个功能开始验证一是用 GM_registerMenuCommand 做一个开关式配置菜单二是用 GM_xmlhttpRequest 请求一个跨域接口并把结果渲染到页面。这两步跑通就等于打通了油猴脚本最核心的“配置 - 存储 - 请求 - 渲染”链路。最容易踩的坑集中在脚本头部声明。记住一句话页面匹配不对脚本不运行grant 声明不对API 报未定义。批量任务没有落盘状态页面一刷新就从头来。把这三个坑避开油猴的体验会顺畅很多。后续值得扩展的方向有三个把任务队列和断点续跑做成通用模块用油猴脚本对接本地 OCR 或翻译服务以及把页面数据导出为 Markdown 或 JSON 文件。这些方向都适合先写最小脚本验证再逐步扩展成完整的工具链。建议先收藏这篇文章等真正开始写脚本时按章节查阅。油猴这个工具上限很高关键在于你有没有把它当成一个“浏览器侧的开发平台”来用。
返回列表