[返回编程技术首页]·[所有跟帖]·[ 回复本帖 ] ·[热门原创] ·[繁體閱讀]·[坛主管理]

【轻松上手】油猴脚本开发(下)

送交者: wecode[☆★声望品衔7★☆] 于 2024-02-03 12:13 已读 1927 次 4赞  

wecode的个人频道

+关注

实践:打印 Hello, World

做一个非常简单的小练习:创建一个名为 "Hello" 的脚本,当进入掘金和知乎页面时,在 Console 中打印 "Hello, World"。



新建脚本


修改脚本名称


指定运行地址 @match@include


直接使用 console.log 或者声明权限调用 GM_log


js


复制代码


// ==UserScript==


// @name         Hello


// @namespace    http://tampermonkey.net/hello


// @version      0.1


// @description  try to take over the world!


// @author       You Name


// @match        https://zhihu.com/*


// @match        https://juejin.cn/*


// @grant        GM_log


// ==/UserScript==

(function() {


    'use strict';


    GM_log("Hello World");


})();

搭建舒适的开发环境

使用在线编辑器小试牛刀之后,或许你也发现在线编辑器


缺少语法补全和自动提示


难以格式化代码


不免怀念起 VSCode。


或许你还会有更深远的考虑,在线编辑器编辑完成后:


怎么同步到远程仓库,怎么做代码分发


如果要用到新语法,怎么保证跨浏览器兼容性


如果代码越写越多,没有模块化怎么管理


没有 TS,很难保证长期维护


这些坑我已经踩过了,并且抽出一个脚手架工具 create-tampermonkey - npm (npmjs.com),一键搭建舒适的油猴脚本开发环境。



脚手架集成 rollup + babel + eslint + typescript,支持:


自动生成 UserScript Header


语法和类型系统:ESNext、ES Module、TypeScript


样式系统:CSS Modules,以及 scss、sass、less、stylus(需安装对应依赖)


静态资源:导入图片、SVG 转换为 Base64,同时支持 SVG Sprite


多语言


扩展:基于 Rollup,可以按需安装插件进行扩展


create-tampermonkey 启动项目

初始化项目


sh


复制代码


npx create-tampermonkey demo-userscript


或者


npm init tampermonkey demo-userscript


或者


yarn create tampermonkey demo-userscript

初始化完毕后,进入目录安装依赖


npm run dev 跑起开发模式



到浏览器中打开 dev.user.js,自动进入 Tampermonkey 脚本安装界面



最后一步:访问 chrome://extension,找到油猴插件的卡片,点击 Details 进入配置界面



勾选 Allow acess to file URLs



刷新页面,出现弹窗,一切就绪。



用 VSCode 打开项目,这时右下角会推荐一些辅助插件,建议安装。


代码中使用到的 GM_xxx 会自动提取到 UserScript Header 中,当然也可以在 src/meta.json 中自定义。


代码的默认入口是 src/main.js 文件。


实践:掘金签到功能

基于上面初始化的项目 demo-userscript 做一个小功能:掘金签到功能。


1. 定位请求


“掘金签到”本质是调用接口,我们的实现思路是追踪点击“立即签到”按钮时请求发送情况,定位到



2. 调试接口


打开 Postman 做一下调试,这里有一个导入小技巧。


右键拷贝 cURL



到 Postman 中通过 curl 导入整个请求:点击左侧面板中的 import 按钮,选择 Raw text 粘贴上一步复制的内容即可。



3. 获取参数



在 Postman 中发现请求需要 aiduuid_signature 三个参数,试试看不带参数能否请求成功,先确定好必不可少的参数和请求头。


简单尝试后,发现这里并不需要带 aiduuid_signature 三个参数,主要是依赖 cookie,使用 GM_xmlhttpRequest 会自动带上对应的 cookie,事情变得简单。


修改 src/main.js 的代码


js


复制代码


GM_xmlhttpRequest({


  url: "https://api.juejin.cn/growth_api/v1/check_in",


  method: "POST",


  headers: {


    "content-type": "application/json",


    "user-agent": navigator.userAgent,


  },


  responseType: "json",


  0nload(response) {


    if (response.status === 200) {


      const data = response.response;


      if (data.data === "success") {


        alert("签到成功");


      } else {


        alert(data.err_msg);


      }


    }


  },


});

刷新页面测试一下。在其他站点刷新一下居然也可以发送请求,这就是插件没有跨域限制的优势了。


再做一下节流优化。利用 GM_setValueGM_getValue 做持续存储。


js


复制代码


const storageKey = "last_sign_timestamp";


// 获取上一次签到的日子


const lastSignNumberOfDays = GM_getValue(storageKey, 0);


// 计算现在所在的日子


const currentNumberOfDays = Math.floor(


  new Date().valueOf() / 1000 / 60 / 60 / 24


);

// 如果今天已经请求过,不再请求


if (currentNumberOfDays !== lastSignNumberOfDays) {


  GM_xmlhttpRequest({


    url: "https://api.juejin.cn/growth_api/v1/check_in",


    method: "POST",


    headers: {


      "content-type": "application/json",


      "user-agent": navigator.userAgent,


    },


    responseType: "json",


    0nload(response) {


      if (response.status === 200) {


        const data = response.response;


        if (data.data === "success") {


          alert("签到成功");


        } else {


          alert(data.err_msg);


        }


        // 更新最近一次签到的日子


        GM_setValue(storageKey, currentNumberOfDays);


      }


    },


  });


}

难免会遇到需要获取数据的情况,可访问的数据一般有三种:


页面中包含数据,通过 DOM 获取


通过接口请求得到


存储在本地存储中,localStorage 或 cookie 之类


确定方式很粗暴:


复制参数或参数值到 Element 中搜索;


查看前面几个请求,看看是否有迹可循;


到 localStorage 或 cookie 中搜索。


分发脚本

在本地开发完脚本之后,npm run build 构建生产版本并上传代码到 Github 或 Gitee。


用 Github/Gitee 上文件的 Raw URL 就能直接实现分发。如果在 package.json 中设置好 repositorycreate-tampermonkey 会自动生成 Raw URL 并赋给downloadURLupdateURL


但这样分发存在的问题是无法统计下载量、从网络访问的角度考虑同时维护 Github 和 Gitee 两个仓库。另一种分发方式是上传到脚本平台 greasyfork.org/ , 登录后即可发布新脚本,如果代码托管在 Github 或 GitLab 还可以使用 Webhooks 实现自动更新。


开发技巧

调试油猴脚本

油猴脚本的运行依托于 background scriptcontent script,在调试前需要对运行环境有所区分,例如 GM_xmlhttpRequest 请求是 background script 发出的,DOM 处理和脚本逻辑是 content script 执行的。


确定环境之后,就可以使用对应的调试方式进行调试了。


调试 background script


还是访问 chrome://extension,找到油猴插件的卡片



inspect views 后面有个 background.html,点击一下弹出 background script 的调试弹窗。


调试 content script


在网页 inspect -> Sources -> Page 下找到 Tampermonkey 目录,页面中运行的油猴脚本代码都在这了,选择目标,断点调试即可。



获取 userId 等信息

有时候需要拿一些额外信息做请求,一般有三种方式:


看看能不能在页面中搜索到,通过 DOM 获取


看看有没有接口可以调用获取


看看本地存储里有没有


目标 DOM 节点未挂载怎么办?

如果节点是在首屏加载的,粗暴的方法是使用 setTimeout 做一下延时。


但如果是在交互过程中有 DOM 更新,就只能引入监听机制了,使用 MutationObserver 来实现。


具体的实例可以看 【开发记录】掘金 “破圈行动” 辅助脚本 - 掘金 (juejin.cn)


查看插件源码

浏览器插件安装之后,插件包被下载到本地目录中,可通过下述方法访问。


访问 chrome://version,找到 Profile path(存放用户数据的路径)


访问 chrome://extensions/,找到目标插件的 ID



将 Profile Path 和插件 ID 拼装在一起 ${Prifile Path}/Extensions/${Extension Id},便是插件包的路径了。友情提示,通过命令行访问时需要在空格前加个 转义一下。


总结

浏览器插件利用浏览器能力进行功能扩展,具有跨域请求、读取 cookie、管理历史记录、注册右键项等能力。


浏览器插件的能力很丰富,能够实现复杂的功能。但如果只是做一些针对页面的操作,只需要依赖基础能力,完全可以使用油猴脚本实现,开发更便捷分发更迅速。


开发油猴脚本,主要是使用 Tampermonkey API 和 JavaScript。


create-tampermonkey 脚手架提供一个全面的油猴脚本开发环境,依托这个环境,可以使用最新的 ES 语法、TypeScript、CSS Modules,在 VSCode 中进行模块化开发,大大提高开发效率。


开发完毕的油猴脚本可通过 Github/Gitee Raw URL 或 Greasy Fork 平台分发。


浏览器插件的主要分工为 background scriptcontent script 两部分,在调试油猴脚本时需要思考清楚是哪一部分出现的问题,再采用对应的调试方式。


实现了两个小实践,走出第一步,接下来尽情发挥创造力吧,玩得开心~

喜欢wecode朋友的这个贴子的话, 请点这里投票,“赞”助支持!

内容来自网友分享,若违规或者侵犯您的权益,请联系我们

所有跟帖:   ( 主贴楼主有权删除不文明回复,拉黑不受欢迎的用户 )


用户名: 密码: [--注册ID--]

标 题:

粗体 斜体 下划线 居中 插入图片插入图片 插入Flash插入Flash动画


     图片上传  Youtube代码器  预览辅助



[ 留园条例 ] [ 广告服务 ] [ 联系我们 ] [ 个人帐户 ] [ 创建您的定制新论坛频道 ] [ Contact us ]