希望用油猴做一些自动化的工具. 不用自动化测试软件的原因是特征都能被浏览器和页面检测出来, 所以这就存在一些风险. UiBot RPA虽然也可以, 没有检测痕迹, 但一是感觉软件太重了, 二是只能解决一些简单的Web上的问题, 很多时候复杂的问题如shadowRoot还需要配合js代码注入, 三是Uibot的代码编辑页实在有点难用,仿VB语言的算法也实在不太适应,尤其是不等号<>, 还有赋值和比较都是=不区分, 四是缺乏第三方库.
先推荐一个教程, 据说是中文唯一写的好的. https://github.com/scriptscat/tampermonkey-learn-guide
油猴官方可以说没有教程tutorial, 只有按字母序排列的API的说明. 虽然会JS上手也能写, 但只有明白额外的API才能进阶高级, 感觉有点像是electron, 不知道油猴是不是能实现类似electron的效果?

油猴名字

油猴这个翻译其实是grease monkey, 代码里简称的GM就是. 而tamper monkey是破坏猴的意思.

// @

最前面的注释部分, 以// @开头的其实都是给油猴看的代码, 类似于预定义, 是和油猴交互的关键. 其中最重要的一定要改的部分呢列出来.

//@命令 子命令 解释
//@name 名称 脚本名称
//@match 网址 匹配网址, 也就是在哪个网址运行. 支持通配符*
// @grant none 脚本直接注入window环境, 同时也不能使用GM_*命令了,所以一般不用
- unsafeWindow 直接使用页面中的任何脚本. 这就会打通页面和本地,理论上页面可以窃取本地内容并操控本地的一切. 脚本中的window需要替换为unsafeWindow
- GM_* 申请指定的GM函数权限.页面window环境需要用unsafeWindow访问.
- GM_xmlhttpRequest 允许跨域请求API
- GM_setValue/ GM_getValue/ GM_deleteValue/ GM_addValueChangeListener/ GM_removeValueChangeListener/ GM_listValues 设置/获取/删除/监听/停止监听/列出本地键值对
- GM_registerMenuCommand /GM_unregisterMenuCommand 在油猴按钮上注册菜单
- GM_addStyle 增加
- window.onurlchange/.close/.focus 这三个window权限需要grant声明才能用
// @run-at document-start 在document加载时就尽快调用脚本(比页面脚本更早)
context-menu 右键增加tempermonkey菜单,子菜单为本脚本名称, 点击运行
// @connect 网址 允许被GM_xmlhttpRequest请求的网址
// @require js文件URL#md5=xxxx 加载外部js资源文件并附带md5校验.引入油猴环境还是页面环境要看@grant定义. 也可以通过在html中插入script的方式来引用
// @resource css css文件URL 加载外部css

常用js代码部分

在html中增加元素

let div = document.createElement("div");
div.innerHTML = '<span>span1</span><span>span2</span>';
// 插入到页面的body中
document.body.append(div);

在html中增加按钮并监听

监听单个元素

let btn = document.createElement("button");
btn.innerHTML =
  "按钮文字,其实也可以写html,变成下面的样子(不过谁用按钮来包那么多html标签呢)";
//innerText也可以,区别是innerText不会解析html
btn.onclick = function () {
  alert("点击了按钮");
};
document.body.append(btn);

监听多个元素

let div = document.createElement("div");
div.innerHTML =
  '<span id="span-1">span1</span><span class="sp">span class</span>';
div.onclick = function (event) {
  if (event.target.id == "span-1") {
    alert("span-1被点击了");
  } else if (event.target.className == "sp") {
    alert("sp这一类被点了");
  }
};
document.body.append(div);

用事件监听器去减轻监听

div.addEventListener("click", function (ev) {
  console.log(ev);
});

在html中插入script

let script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.src = "https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.min.js";
document.documentElement.appendChild(script);

在html中插入css

let script = document.createElement('link');
script.setAttribute('rel', 'stylesheet');
script.setAttribute('type', 'text/css');
script.href = "https://blog.icodef.com/wp-content/themes/Kratos-3.0.7/assets/css/kratos.min.css?ver=3.2.4";
document.documentElement.appendChild(script);

直接用GM_addStyle插入样式

GM_addStyle("#HMRichBox{display:none !important}");

在页面加载完毕后再执行

等所有元素加载完毕(包括图像等)

    window.onload = ()=>{
        alert('loaded')
    }

在油猴按钮上注册菜单 GM_registerMenuCommand

let id = GM_registerMenuCommand(
  "自定义的菜单",
  function () {
    alert("菜单被点击");
    GM_unregisterMenuCommand(id); //删除菜单
  },
  "h"  // 这个是accessKey, 快捷键
);

其他问题

如何对付嵌套iframe的页面

要看iframe打开的是哪个url, @match进去就好

如何劫持js页面函数

在window下面的函数都可以直接劫持. 如 window.setInterval = 自己的函数, 页面中自定义的函数也可以这么劫持, 如window.页面函数 = 自己的函数
几个常常劫持的函数, 除了setInterval函数劫持后可以改变时间帧间隔外, XMLHttpRequest函数劫持可以获取网络请求. 比如劫持XMLHttpRequest.prototype.send就可以修改发送的内容.
除了用XMLHttpRequest,页面还可能用fetch获取服务, 这时候需要对fetch劫持

let oldFetch = fetch;
function hookFetch(url, init) {
  //这里进行提交内容劫持
  return oldFetch.apply(this, arguments);
}
window.fetch = hookFetch;

对事件监听器劫持

const oldEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (...args) {
  console.log("addEventListener Hook", this, ...args);
  return oldEventListener.call(this, ...args);
};

其他可以劫持的还包括window.WebSocket
还可以劫持原型链上的函数. 如某个object.func()在其原型链上, 可以object.prototype.func = 自己的函数

如何在代码中打断点

在代码中使用debugger;命令,F12打开时就会停在这儿

标签: none 阅读量: 205

添加新评论