Tampermonkey油猴脚本指南:安装配置到自写脚本
浏览器里装一个扩展网页上就能多出原本不存在的按钮、自动翻页、批量导出、去广告、表单自动填充——这套玩法的核心工具就是 Tampermonkey圈子里习惯管它叫油猴脚本管理器。我用了快六年从最早只是装别人写好的脚本到后来自己写脚本改页面踩过的坑能写满两页纸。这篇就把 Tampermonkey 的安装、配置、脚本获取到自写脚本的完整链路讲透顺带把那些文档里不会写的细节一并交代清楚。如果你只是想在浏览器上加个顺手的小功能看完前两章就够了如果你想自己动手写脚本第五、六章是你的重点。不管你是完全没接触过用户脚本的新手还是装过脚本但一直没搞明白原理的老用户下面这些内容应该都能对得上。1. 油猴脚本到底是什么先把概念捋直很多人第一次听到“油猴”这个词脑子里是懵的。它既不是浏览器也不是某个网站而是一个浏览器扩展——准确说叫用户脚本管理器。它的作用只有一件事让你能在别人网站的页面上运行一段自己写的或别人写的JavaScript。这段 JavaScript 就叫“用户脚本”英文 UserScript。理解了这个后面的所有操作逻辑就顺了。Tampermonkey 本身不提供任何功能它只是一个“运行器”和“管理器”。真正干活的永远是脚本。所以经常有人问“装了油猴怎么没反应”答案通常是你只装了运行器没装脚本。这两件事必须分开看。1.1 用户脚本管理器到底在管什么拆开来看一个用户脚本管理器至少负责四件事。第一是注入把脚本代码在合适的时机塞进目标页面第二是匹配判断当前访问的网址该不该运行这个脚本第三是隔离让脚本运行在一个相对独立的环境里避免和页面自身的代码互相污染第四是管理包括启用禁用、更新、排序、导入导出。这四件事听起来简单但每一件都有讲究。比如注入时机早了页面还没渲染完脚本找不到元素晚了用户已经看到内容闪了一下。比如匹配规则写得太宽会在不该运行的站点上乱跑写得太窄又会漏掉子域名。再比如隔离Tampermonkey 默认把脚本放在沙箱里跑好处是安全坏处是你访问不到页面自己的全局变量得用unsafeWindow这个特殊对象绕过去。提示弄清“管理器”和“脚本”是两回事能省掉你后面八成的困惑。装完扩展发现没效果第一反应应该是“我装脚本了吗”而不是“扩展是不是坏了”。1.2 为什么是 Tampermonkey而不是别的同类工具不止一个但 Tampermonkey 是生态最完整、兼容性最好的那个。它几乎覆盖了所有主流内核的浏览器脚本的元数据语法支持得最全社区里现成的脚本也基本都以它为基准来写。换成别的管理器经常会出现某个GM_开头的接口不认、某个元数据字段被忽略的情况。还有一点实际体验上的差别它的脚本编辑器和调试信息做得比较顺手。写脚本的时候可以直接在浏览器里改、保存、刷新验证不用来回切编辑器。对于需要反复试错的小脚本来说这个效率差距挺明显。当然也不是没代价。它的功能多设置项就多第一次打开设置页面容易被一堆选项吓到。我的建议是先别碰设置默认配置对 95% 的场景都够用等你真的遇到具体问题再去翻对应那一项。2. 安装前必须先搞清楚的三件事直接冲去搜索然后点安装出问题的概率不低。我自己就干过在错误的商店页面装了个同名的冒牌扩展装完浏览器首页被改了。所以动手之前先把这三件事确认清楚能避免很多返工。2.1 你的浏览器内核和版本够不够Tampermonkey 支持的是基于 Chromium 和 Gecko 两大内核的浏览器。国内常见的双核浏览器一个内核渲染普通页面一个内核兼容老系统情况要复杂一些——它们的内核版本往往落后官方好几个大版本扩展商店里的版本可能装不上或者装上了但某些接口不可用。判断方法很简单在浏览器地址栏输入about:version部分浏览器是chrome://version看里面的内核版本号。如果主版本号落后当前主流版本太多比如差了三四十个大版本那就要做好“能装但可能出怪问题”的心理准备。遇到这种情况我一般建议换个内核版本新的浏览器专门用来跑脚本别在主浏览器上折腾。另外要注意的是扩展商店的可用性。有些浏览器自带的应用商店里搜不到 Tampermonkey或者搜到的是很久没更新的旧版本。这时候不要随便找个第三方站点下载.crx文件硬装风险太高了。2.2 三个安装渠道的取舍渠道优点风险建议浏览器官方扩展商店自动更新、来源可追溯部分商店可能未收录首选扩展的官方站点跳转版本最新、渠道正规需要确认跳转地址正确次选第三方站点下载安装包什么浏览器都能装包可能被篡改、无法自动更新尽量避免我把这张表放在这里是因为见过太多人栽在第三条上。扩展这个东西权限很高它能读取你访问的所有页面的内容能代表你发起网络请求。一个被改过的安装包等于把浏览器的钥匙交给了不明来源。为了省那几分钟不值当。注意如果你用的浏览器实在没有可用的扩展商店宁可放弃这个工具也不要从搜索结果里随便点一个“高速下载”按钮。这类站点捆绑安装是常态。2.3 装之前先想清楚要拿它干嘛这听起来像废话但实际很有用。Tampermonkey 的价值完全取决于你装的脚本。如果你只是听说这东西很厉害就装了装完大概率会在扩展栏里吃灰三个月然后被卸载。比较务实的心态是先遇到一个具体的麻烦再去想脚本能不能解决。比如某个站点每次都要手动点五次才能导出数据比如某个页面字体小得看不清比如某个后台系统需要反复填同样的表单。这些「重复动作」才是用户脚本真正的主场。带着具体需求去装装完立刻能用上正反馈才立得住。3. 分场景安装实操一步步走完确认完前置条件就可以动手了。虽然安装本身只有几步但不同环境下的细节差异不小分开说更清楚。3.1 桌面端浏览器的完整安装流程以最常见的 Chromium 内核浏览器为例整个流程大概是这样打开浏览器的扩展管理页面。地址栏输入chrome://extensions不同浏览器前缀可能不同有的是edge://、brave://。确认右上角的「开发者模式」开关状态。装扩展本身不需要打开它但如果你后面要手动加载本地脚本包就必须要开。进入浏览器官方的扩展商店搜索Tampermonkey。认准开发者信息和用户量。正版扩展的用户量通常在百万级别且更新记录持续。名字一样但用户量只有几千的基本可以判定为仿冒。点击「添加到浏览器」弹窗里确认权限。安装完成后浏览器工具栏会出现一个黑白两色的图标。如果没看到点一下工具栏的拼图形状按钮把这个图标固定到显眼位置。第 6 步容易被忽略。很多浏览器的工具栏默认只显示少数几个扩展新装的会被折叠进二级菜单。我见过有人装完之后满世界找图标以为没装上其实只是被收起来了。安装成功的标志是点击图标能弹出一个面板里面有「已安装脚本」「设置」「实用工具」这几个入口。看到这个面板说明运行器到位了。3.2 装完之后的第一次配置刚装好的默认状态其实已经能用了但有几个地方我建议顺手调一下后面会省事。第一打开「设置」里的脚本更新检查。默认是每周检查一次如果你装的脚本比较多可以改成每天。脚本作者修 bug 往往很及时多检查几次能少踩一些已经修好的坑。检查频率设太高也没必要一天一次足够。第二确认「配置模式」选的是「新手」还是「高级」。新手模式下很多选项是隐藏的界面上没那么吓人。等你需要改grant相关的行为、或者要调试沙箱问题了再切到高级。我自己的习惯是一直留在高级因为经常要手动改脚本的权限声明切来切去麻烦。第三设置一个固定的备份目录。这个在「实用工具」标签页里可以把所有已安装的脚本导出成一个压缩包或单个文件。养成定期导出的习惯换电脑、重装浏览器的时候一键导入不用一个个重新装。我自己是每加五六个新脚本就导一次文件不大但救过我好几次。提示导出的备份文件里包含脚本的完整代码不要随手丢在公共网盘或者聊天群里。有些私人定制脚本里会有内部系统的地址泄露出去不太合适。3.3 移动端到底能不能用这是被问得最多的问题之一。结论先说绝大多数手机浏览器不支持安装这类扩展原因是移动端浏览器的扩展体系普遍是封闭的只有极少数产品开放了扩展接口。市面上有几种绕路方案比如某些支持用户脚本的定制浏览器、或者通过其他方式注入脚本。这些方案各有各的限制要么脚本兼容性差很多GM_接口用不了要么配置过程繁琐。我自己在手机上试过几次最后的结论是如果需求简单用浏览器自带的阅读模式、简页模式基本能覆盖如果需求复杂还是回电脑上做。真有移动端刚需的场景比如需要在手机上自动填某个表单我的建议是把脚本逻辑简化到只依赖原生 JavaScript 和 DOM 操作避开所有GM_前缀的接口这样兼容性会好很多。但这属于比较进阶的玩法新手不建议从这里入门。4. 脚本的获取、安装与管理到这一步运行器已经就位接下来是往里面装真正干活的东西。4.1 脚本来源怎么挑现成的脚本主要集中在几个大型的脚本分享站点上。这些站点的内容由用户自发上传质量参差不齐没有任何官方审核。这意味着你必须自己判断一个脚本值不值得信任。我的判断顺序是这样的看代码长度和复杂度。一个只做页面样式微调的脚本几十行就够了。如果标称“去广告”代码却有三千行还混淆过直接跳过。看最近更新时间。网站改版很频繁超过一年没更新的脚本大概率已经失效了装了也是白装。看评论区。分享站点一般有反馈区翻最近几条看看有没有人报“不生效”“报错”这类问题。作者的回复态度也是参考。看权限声明。脚本头部会写明它需要什么权限grant里如果出现发起跨域请求、读写本地存储这类就要多留个心眼。最关键的一条任何要求你输入账号密码的脚本一律不装。正规的用户脚本不需要这个它运行在你已经登录的页面环境里压根拿不到也不需要你的密码。出现这类要求的基本可以直接判定为钓鱼。4.2 安装一个脚本的完整动作流程本身不复杂但有几个卡点值得提前说。在脚本分享站点找到目标脚本点击「安装」按钮。正常情况下浏览器会自动唤起 Tampermonkey 的安装确认页页面上会列出脚本的名称、版本、作者、以及它会在哪些网站上运行这一栏最关键。仔细看「匹配的网站」那一栏。如果你只想让它在一个站生效结果列表里出现了十几个不相关的域名那就得掂量一下了。点击「安装」脚本进入已安装列表默认是启用状态。打开目标网站刷新页面验证效果。卡点一点了安装没反应。通常是浏览器拦截了跳转地址栏右侧会出现一个被拦截的提示手动允许一次就行。也可能是脚本站点用的链接格式不对这时候可以手动复制脚本源码在 Tampermonkey 面板里点「新建脚本」把代码粘贴进去覆盖模板。卡点二装完之后脚本列表是空的。检查一下是不是装到了别的浏览器配置文件下。有些浏览器支持多用户配置扩展是按配置隔离的你在 A 配置里装的B 配置里看不到。卡点三脚本显示已启用但页面没变化。先按 F12 打开开发者工具切到 Console 标签刷新页面看有没有红色报错。如果有把报错信息记下来这基本就是问题定位的起点。如果没有报错但也没效果那就是脚本的匹配规则没覆盖当前网址或者页面结构已经变了。4.3 管理面板里真正有用的几个功能Tampermonkey 的面板功能不少但日常高频用到的就这几个脚本列表的开关。每个脚本前面有个开关临时禁用不用卸载排查冲突的时候特别有用。我排查“到底哪个脚本把页面搞崩了”的时候就是一半一半地关二分法定位几十秒就能锁定。编辑器。点脚本名称进入编辑界面可以直接改代码CtrlS保存后刷新页面立即生效。这个即时反馈的体验很关键写脚本的时候大部分时间都花在这个循环里。「设置」里的「存储」标签。脚本用GM_setValue存的数据都在这里能看到每个脚本占用了多少空间。有时候脚本行为异常是因为存的数据格式和旧版本对不上清一下存储就恢复了。「实用工具」里的导入导出。前面提过不再重复。补充一点导入的时候可以选择「合并」还是「替换」默认是合并同名脚本会被新版本覆盖。如果你改过某个脚本的代码导入前记得单独备份不然会被冲掉。5. 自己动手写脚本从元数据开始装别人的脚本用久了总会遇到“这个功能差一点点就完美了”的情况。这时候自己动手改比到处找替代品效率高得多。写用户脚本的门槛其实比想象中低会一点 JavaScript 和浏览器开发者工具的基本用法就能起步。5.1 元数据块逐字段拆解每个用户脚本的头部都有一块被// UserScript和// /UserScript包起来的注释叫元数据块。管理器靠它判断脚本的身份和行为。下面这份是我常用的模板// UserScript // name 页面小工具示例 // namespace local.demo.tools // version 1.0.0 // description 演示用的最小可运行脚本 // author demo // match https://example.com/* // grant none // run-at document-end // /UserScript逐行说重点name是显示名称随便起但建议带上用途装多了之后一眼能认出来。namespace是个唯一的标识前缀作用是区分同名脚本。两个脚本name一样但namespace不同会被当成两个独立脚本共存。自己写的脚本建议用固定的前缀比如你的昵称加个点。version影响更新判断。你改了代码但版本号没动管理器不会认为这是新版本。手动改脚本的时候养成顺手加版本号的习惯不然导出的备份和线上版本容易搞混。match是最关键的字段决定脚本在哪些网址生效。语法格式是协议://主机/路径支持*通配。几个容易写错的点https://example.com/*只匹配主域名不匹配www.example.com和任何子域名。要匹配所有子域名得写https://*.example.com/*。*://example.com/*表示不限制协议但实际用的时候建议明确写https避免在 http 页面上也触发。路径部分的*是贪婪匹配会跨越斜杠。grant声明脚本需要的特殊接口权限。写none表示不需要任何特殊权限脚本直接跑在页面环境里写法最简单。如果需要用GM_setValue存数据、GM_xmlhttpRequest发跨域请求就得把对应的名字列出来。列了权限但没用会影响脚本的加载方式用了接口但没列权限直接报错。这个对应关系必须严格。run-at控制注入时机四个常用值取值时机适用场景document-start文档开始加载DOM 还没建需要在页面脚本之前抢先执行、或者要拦截某些请求document-bodybody 出现时少数需要尽早操作 body 的场景document-endDOM 解析完成资源可能还在加载绝大多数操作 DOM 的脚本document-idle页面完全加载完毕需要等图片、异步内容都就位的场景新手默认用document-end能解决九成问题。如果你发现脚本执行时目标元素还不存在先试着往后挪到document-idle比手动写一堆延时靠谱。5.2 一个能跑起来的最小脚本讲理论不如看实物。下面这个脚本做的事情很朴素在页面右上角加一个固定按钮点一下把页面正文的背景色切成护眼色再点一下切回来。// UserScript // name 护眼背景切换 // namespace local.demo.eyecare // version 1.0.0 // description 一键切换页面背景为护眼色 // match https://example.com/* // grant none // run-at document-end // /UserScript (function () { use strict; var toggled false; var btn document.createElement(button); btn.textContent 护眼; btn.style.cssText [ position:fixed, top:80px, right:16px, z-index:99999, padding:6px 12px, border-radius:6px, border:1px solid #ccc, background:#fff, cursor:pointer, font-size:13px ].join(;); btn.addEventListener(click, function () { toggled !toggled; document.body.style.background toggled ? #c7edcc : ; }); document.body.appendChild(btn); })();拆一下这段代码里的几个决定每个都有理由外面套了一层立即执行函数。用户脚本虽然没有模块系统但页面可能有别的脚本也在用同名变量。包一层函数形成局部作用域能避免污染全局。这是写用户脚本的基本纪律别省。用了use strict。严格模式能帮你抓出一些低级错误比如给未声明的变量赋值。脚本跑在别人页面上出错了不好调试提前严格一点划算。样式用cssText一次性写入。比逐个设style.top ...少写很多行而且减少浏览器重排次数。z-index给了99999是为了压过页面自身的高层级元素。这个值不是越大越好给到 99999 一般够用给到 2147483647 反而可能和其他浮层打架。按钮位置选了top:80px; right:16px。这个位置是我试出来的——太靠上会和页面自己的导航栏重叠太靠右会被滚动条挡住。实际写的时候你可以先用position:fixed随便放个位置然后拖到不碍事的地方记下坐标。没有做「页面切换后恢复」的处理。这是个已知的局限单页应用里路由切换后DOM 被替换按钮会消失。要解决这个问题得监听 URL 变化属于进阶内容先不展开。这里提一句是想说明写脚本的第一步是先让它能跑别一上来就追求完美。5.3 调试和权限两个最容易出问题的环节调试用户脚本和调试普通页面代码有个关键差别。当grant是none时脚本运行在页面上下文中控制台里能直接看到变量一旦列了任何GM_接口脚本就进了沙箱控制台的作用域会变成 Tampermonkey 自己的页面变量访问不到。这个差别导致的现象是同样的代码改了一行grant就报“xxx is not defined”。解决方法有两个要么用unsafeWindow.xxx显式访问页面的全局对象要么把需要的数据通过 DOM 或者GM_setValue中转一下。另一个高频问题是跨域请求。脚本里直接用fetch请求别的域名大概率被浏览器的同源策略拦掉。这时候要用GM_xmlhttpRequest它绕过了页面的同源限制。但光在grant里声明还不够还得在元数据里加一行connect指定允许请求的域名// grant GM_xmlhttpRequest // connect api.example.comconnect不写或者写成*安装的时候会弹出一个更醒目的权限提示用户看到会犹豫。自己的脚本自己用无所谓要分享给别人就该把域名写死让人放心。注意GM_xmlhttpRequest能绕同源限制这意味着脚本理论上可以把当前页面的数据发到任意服务器。这也是为什么前面反复强调不要装来源不明的脚本——它的能力边界比很多人想象的大。6. 常见问题与排查实录下面这些是我这几年被问得最多的、以及自己踩过的坑。按出现频率排前面几条基本覆盖了八成的求助。6.1 故障速查表现象最可能的原因排查动作装完脚本没任何变化match没覆盖当前网址面板里看脚本详情核对匹配规则与实际 URL控制台一片红页面改版导致选择器失效看报错行号用 F12 重新确认元素选择器脚本时好时坏注入时机太早元素还没渲染把run-at改到document-idle按钮被页面遮住z-index不够或父级有transform提高层级注意transform会创建新的层叠上下文之前好用突然失效脚本被自动更新成了新版本回退版本或联系作者反馈无痕模式下不工作扩展在无痕窗口默认关闭扩展详情页里手动允许无痕运行两个脚本互相打架同时操作同一块 DOM用二分法逐个禁用定位保存数据下次打开没了用的是localStorage且域名变了改用GM_setValue它跟脚本绑定不跟域名绑定表格只能覆盖典型情况实际排查还得靠方法。我的固定套路是三步F12 看报错 → 断点看变量 → 逐段注释代码缩小范围。第三步最笨也最有效尤其是改别人的脚本时把可疑的代码块注释掉刷新看现象是否消失几次就能定位。6.2 脚本冲突和性能问题脚本装多了页面变卡是常态。原因有几个层面。一层是执行次数。有些脚本在match里写得太宽你在任何网站上它都在跑虽然每次都只是判断一下然后退出但几十个脚本叠加起来页面加载时的那几百毫秒延迟是能感觉到的。解决办法是定期清理三个月没用的脚本直接禁用别舍不得。另一层是DOM 监听。为了实现“页面内容变化后也跟着变”很多脚本会挂MutationObserver。这个东西威力大但用得不好就是性能杀手——监听整个document的子树变化页面稍微动态一点就疯狂触发回调。写的时候要尽量缩小监听范围只盯目标容器并且在回调里做好去抖。还有一层是样式冲突。两个脚本都想改同一个元素的样式谁后执行谁生效。这种情况下改代码不如改思路用更具体的选择器或者干脆把样式加在一个独立创建的容器上避开和页面原有样式的直接竞争。提示判断页面变卡是不是脚本导致的最快的办法是开一个无痕窗口扩展默认不加载对比同一个页面的加载速度。差距明显就是这个原因。6.3 安全边界哪些脚本坚决不碰这一节我认为比前面所有技术细节都重要。用户脚本运行在你已登录的页面里它能读到页面上的一切——包括你的用户名、订单信息、聊天内容。它还能发起请求把这些数据送出去。所以判断一个脚本安不安全本质上是在判断作者有没有动机和能力做坏事。几个硬性红线要求输入账号密码的不装。代码被混淆成一堆无意义字符、完全读不懂的不装。正常脚本没必要混淆。声明了大量connect到不相关域名的不装。承诺“破解”“解锁会员”的不装。这类脚本要么无效要么来源可疑。分享站点上刚注册的新账号发布、零评论零更新的先观察。相对安全的做法是优先选那些更新记录长、评论区活跃、作者有多个作品的脚本。要更稳妥就自己去读一遍源码重点看有没有往外部地址发送数据的地方。几百行的脚本认真读半小时能看完。7. 一点实际使用下来的体会写脚本这件事最大的门槛其实不在语法而在于愿不愿意去读别人页面的代码。浏览器开发者工具里的元素面板就是你的地图。想改什么先在那里找到对应的节点看清楚它的类名、层级、兄弟元素然后再动手写选择器。我早期写的脚本十有八九失效问题都出在选择器写得太“脆”——依赖了自动生成的类名网站一改版全废。后来学乖了尽量用语义化的属性、稳定的父级结构来定位寿命能长好几倍。另外一个我想强调的点是别把脚本当成万能药。有些需求用脚本硬做要写几百行还容易崩换成别的方式比如浏览器自带的阅读模式、或者干脆换个更顺手的工具可能五分钟就解决了。判断标准很简单——如果这个脚本你需要维护那它就是在给你增加负担而不是减少。最后分享一个我一直在用的小习惯给每个自己写的脚本都在description里写清楚「解决什么问题」和「上次验证日期」。半年后回头翻你会感谢当时的自己。脚本这东西写的时候记得清清楚楚放三个月再看就是天书了。