第一个Tampermonkey脚本

初遇 Tampermonkey
某一个夜晚, 在我准备出去吃饭的时候, 浏览器突然蹦出来油猴脚本的更新提示, 虽然不是很想鸟它, 但是不知道怎么就也突然想学油猴脚本了
虽然不是第一次使用油猴脚本, 但是自己也只是在网上找找现成的脚本直接安装, 也是突然就想学习一下具体的语法
一开始在 B 站找了个视频, 发现没有任何屁用, 于是打开浏览器寻找, 结果还真给我找到一个非常不错的教程
教程链接如下 : 油猴开发指南
学习油猴脚本需要有前端编程的经验, 很不巧刚好会前端 ~~~~, 于是便开启了我的脚本之路….
油猴脚本概述
所有油猴脚本, 实际上就是一个前端 js 代码植入, 通过这些 js 代码来实现我们的一些功能
一个基本的油猴脚本内容如下所示
// ==UserScript==
// @name New Userscript
// @namespace http://tampermonkey.net/
// @version 2024-04-09
// @description try to take over the world!
// @author You
// @match http://*/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Your code here...
})();
我们主要讲解一下上面的几个注解:
@name
: 这个脚本的名字
@version
: 这个脚本的版本
@description
: 这个脚本的描述
@author
: 这个脚本的作者
@match
: 这个脚本所适配的网站, 可以有多个, 可以使用通配符*
更多的注解可以查阅官方文档 : 注解官方文档
虽然有些也解释的不明不白….建议不明白直接百度…
油猴脚本实践
虽然才看了这么点内容, 但毕竟脚本的核心是 js 代码, 而我对js 代码还算熟悉, 于是直接上手
我早就对 SCNU 的砺儒云课堂非常不满了, 不能保留用户登录信息, 每次登录还挺麻烦的
于是我打算写一个脚本来实现自动化登录
主要的脚本代码如下 :
// ==UserScript==
// @name 砺儒云课堂自动登录程序
// @namespace https://moodle.scnu.edu.cn/
// @version 1.0.0
// @description 帮助你自动登录SCNU课程网站-砺儒云课堂
// @author yyym
// @match https://moodle.scnu.edu.cn/*
// @match https://sso.scnu.edu.cn/AccountService/user/login.html
// @match https://sso.scnu.edu.cn/AccountService/openapi/auth.html*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @require https://scriptcat.org/lib/513/2.0.0/ElementGetter.js
// @grant none
// ==/UserScript==
(function() {
'use strict';
let username = "username";
let password = "pwd";
/* 首先我们需要获取当前网站的 url
* 因为整个登录过程会跳转到不同的 url, 我希望这个脚本根据不同的 url 来执行不同的逻辑
* 因为 url 有多个, 所以我也在注解中配置了多个 @match
*/
let url = window.location.href;
// 因为网址可能在 ? 带有多个参数, 所以需要过滤掉 ? 后面的参数
let index = url.lastIndexOf('?');
if(index != -1) {
url = url.substring(0, index);
}
// 在主登录页面的逻辑, 即砺儒云首页
if(url == "https://moodle.scnu.edu.cn/") {
// 通过开发者工具找到对应的 DOM 元素
let loginButton = document.querySelector(".forgotpass a");
// if loginButton is null, it mean user has logined
if(loginButton == null) return;
loginButton.click(); // js模拟点击跳转
}
// 在选择统一身份认证还是游客登录的逻辑, 默认统一身份认证
if(url == "https://moodle.scnu.edu.cn/login/index.php") {
// 异步获取 DOM 对象
elmGetter.get('#ssobtn').then(but => {
if(but == null) {
alert("ERROR"); return;
}
but.click();
});
}
// 在输入账号密码的逻辑
if(url == "https://sso.scnu.edu.cn/AccountService/user/login.html") {
// 如果账号密码错误脚本将在这里被停止
let msgtext = document.querySelector("#msgtext");
if(msgtext.innerHTML != "") {
alert(msgtext.innerHTML);
return;
}
let account_input = document.querySelector("#account");
let pwd_input = document.querySelector("#password");
account_input.value = username;
pwd_input.value = password;
let but = document.querySelector("#btn-login");
but.click();
}
// 确认登录逻辑
if(url == "https://sso.scnu.edu.cn/AccountService/openapi/auth.html") {
let confirm = document.querySelector(".login-check-comfirm a");
confirm.click();
}
})();
值得注意的是, 我们在一个 php
页面执行了异步获取元素的操作
这是因为直接使用 document.querySelector("...")
会找不到对象
一般有两种原因, 一个是使用 iframe
框架, 一个是在查找元素的时候页面还没有加载
经过排查属于第二种情况, 所以我打算使用 ElementGetter 库
ElementGetter 库
的使用教程: ElementGetter 库教程