Chrome 自动化交互利器:用 tampermonkey 向页面注入自定义 Javascript

一、背景

常常会遇到相似下面的这种网站,查个信息得填一堆信息,奇葩的是文本框也不让复制粘贴,并且浏览器还不自动保存,这样每次查询或者超时退出都得从新手动填写一遍。javascript

有没有办法能简化这个过程呢?html

办法固然是有的,其中最通用的办法是装个 lastpass 扩展,由它帮你完成表单信息的自动保存与填充,信息也会云存储在他们服务器上,仍是挺方便的。java

可是若是你担忧隐私安全或者想要更加个性化的功能怎么办?通常来讲这个时候须要用户自定义脚原本实现了。node

二、tampermonkey 简介

Chrome是原生支持加载UserScripts的,只不过它的加载方式是将UserScripts文件转换为一个扩展…… 开发起来略麻烦,不过好处就是稳定可靠。不过这个方案在这里就比较重量级了,不够方便。 因此我决定用TamperMonkey来作这件事儿。 安利一下TamperMonkey扩展,这个至关于Firefox上的Scriptish或GreaseMonkey扩展,至关于一个UserScripts的管理和加载器。挺好使的一个玩意儿,做者貌似是位棒子国的同胞,只不过这货对Chrome的性能影响仍是蛮大的。跨域

三、用 tampermonkey 实现自动化交互

首先你须要安装好 Chrome 以及 tampermonkey 插件,而后在你须要自动交互的网站上点击扩展图标,这样你就能够开始写你的交互逻辑代码了:浏览器


上面是一个很通用的模板,若是你看不懂的话也许须要去看下UserScripts的格式…… 这里先把 @name  和 @match  改掉,一个是名字,一个是匹配的网址。名字随便取,@match  改成 http://www.ooxx.com/*。 而后在最下面开始写代码。安全

好比文初开头的完整代码以下:
服务器

// ==UserScript==
// @name         ooxx网站
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        http://www.ooxx.com/wsyw/wscx/gjjcx-logineoor.jsp?id=2
// @grant        none
// ==/UserScript==
/* jshint -W097 */
'use strict';

// Your code here...


(function () {
    document.getElementsByTagName("option")[1].selected = true;
    document.form1.bh.value = "ID:NO";
    document.form1.mm.value = "passwd";

    //function post(path, params, method) {
    //  method = method || "post"; // Set method to post by default if not specified.
    //
    //  // The rest of this code assumes you are not using a library.
    //  // It can be made less wordy if you use one.
    //  var form = document.createElement("form");
    //
    //  form.setAttribute("method", method);
    //  form.setAttribute("action", path);
    //
    //  for (var key in params) {
    //      if (params.hasOwnProperty(key)) {
    //          var hiddenField = document.createElement("input");
    //          //hiddenField.setAttribute("type", "hidden");
    //          hiddenField.setAttribute("name", key);
    //          hiddenField.setAttribute("value", params[key]);
    //
    //          form.appendChild(hiddenField);
    //      }
    //  }
    //
    //  var iframe = document.createElement("iframe");
    //  //document.body.appendChild(iframe);
    //  //document.querySelector("iframe").contentWindow.document.childNodes[0].appendChild(form);
    //  //form.submit();
    //
    //}
    //
    //post('http://lab.ocrking.com/do.html', {
    //  url : 'http://www.ooxx.com/wsyw/servlet/PicCheckCode1',
    //  service : 'OcrKingForCaptcha',
    //  language : "eng",
    //  charset : "7",
    //  outputFormat : "",
    //  email : ""
    //});
})();

这样当你每次打开 http://www.ooxx.com/wsyw/wscx/gjjcx-logineoor.jsp?id=2 时,下拉列表会被选择好,同时各个表单域的值也会填写成预设值,若是验证码也破解成功则能够直接模拟点击事件提交表单,文章开头提到的繁琐流程至此一鼓作气十分方便!app

关于最后一个验证码的破解有两种思路:less

  • 利用Canvas进行验证码识别,属于纯 js 破解,须要针对性的分析验证码的色彩与位置分布特色等,兼容性很差

  • 利用云服务来破解,不过这种须要注意 Ajax 跨域问题,推荐使用 js 构造iframe,而后嵌套 form 表单提交 post 的方式来请求服务

这两点思路能够参考文末的 Refer 连接。

四、个性化需求:目标页自动输入百度网盘密码

咱们应该常常能遇到上面的 case,每次都要打开连接,而后再返回回来复制密码,再切到下一页面,再粘贴回车,太繁琐啦。

我们能够看看在 tampermonkey 中如何将这几个交互步骤自动化。

4.1 给跳转 url 带上尾巴

要想在下一页还能拿到上一页密码,只有两种办法,一种是 url 传参,另外一种是 Cookie 传递。

这里我们优先选择 url 传参的方式,基本意思就是找出全部指向百度网盘、360云盘的A标签,而后尝试在A标签后面的文本或A标签当前上级节点里搜索提取码,一旦找到的话,就将其以Hash的方式附加到连接中。

4.2 提取密码并模拟点击

从上一步中的 URL Hash 中截取密码并赋值给密码框,最后模拟点击事件便可。

代码最终以下:

// ==UserScript==
// @name         zdfans
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        http://www.zdfans.com/*
// @grant        none
// ==/UserScript==
/* jshint -W097 */
'use strict';

// Your code here...
// 4.1
document.querySelectorAll("a[href*='pan.baidu.com'], a[href*='yunpan.cn']").forEach(
    function(link){
        var txt=link.nextSibling&&link.nextSibling.nodeValue; 
        var code=/码.*?([a-z\d]{4})/i.exec(txt)&&RegExp.$1;
        if(!code){
            txt=link.parentNode.innerText;
            code=/码.*?([a-z\d]{4})/i.exec(txt)&&RegExp.$1;
        }
        if(code){ 
            var href=link.getAttribute("href");
            link.setAttribute("href", href+"#"+code);
        }
    }
);


// 4.2
var pathname=self.location.pathname;

!function(){
    if(pathname.indexOf("/share/")!==-1&&document.getElementById("accessCode")){
        var code=self.location.hash.slice(1,5);
        if(/[a-z\d]{4}/i.exec(code)){
            document.getElementById("accessCode").value=code;
            document.getElementById("submitBtn").click();
        }}
}();

须要说明的是,虽然效果很好很赞,但最大的问题是:须要跑UserScripts。因此通常在常去的资源站上用用就行了,不必把脚本跑到每一个网站上,毕竟那是极浪费性能的事儿~

上面我只匹配了zdfans网站,但其实只要改@match ,这段脚本能够匹配大多数使用网盘共享的网站。

最后感谢 木魚 童鞋提供的思路与分享,其实引伸开来,TamperMonkey 用于一些自动化交互测试以及一些什么秒杀活动自动输入等场合也是极好的,就看你们怎么拿着锤子满世界找钉子了~ :)

Refer:

[1] 技术贴:使用UserScript自动经过百度网盘/360云盘提取码

http://blog.fishlee.net/2016/03/09/using-contentscripts-to-pass-access-code/

[2] Javascript : get <img> src and set as variable?

http://stackoverflow.com/questions/7882356/javascript-get-img-src-and-set-as-variable

[3] 使用Canvas进行验证码识别

http://www.cnblogs.com/ziyunfei/archive/2012/10/05/2710349.html

[4] JS破解乌云验证码

http://zone.wooyun.org/content/18101

[5] OCR 在线识别验证码

http://lab.ocrking.com/

[6] UserScript:自动提取XClient上的下载链和提取码

http://blog.fishlee.net/2016/03/18/userscipts-pass-xclient-downloadlink/

相关文章
相关标签/搜索