zoukankan      html  css  js  c++  java
  • 记一次油猴脚本开发笔记

    需求:某网站将自己的下载链接给隐藏了,需要自己获取资源ID再和前缀拼接成资源URL以便下载。

    这一部分用手工做很麻烦,所以打算写个程序来解决。最开始计划写一个谷歌浏览器扩展,但后面突然想到,我还装了个油猴脚本呢,直接写个油猴脚本不是更简单。于是开始了第一个油猴脚本的开发。

    油猴脚本基于JS语言的,然而对于JS我只了解一点皮毛。操作网站肯定要了解HTML,但HTML我更是皮毛都不如,只知道一些标签。没事,不懂才要学嘛。

    首先我们要了解油猴脚本,这部分在网络上有大量的资源,我就简单的介绍一下。

    // ==UserScript==
    // @name         ScriptName  //这个是脚本名
    // @namespace    http://tampermonkey.net/   //这个第一次开发可以忽略
    // @version      0.1  //版本号,在后续更新中会用到
    // @description  用于下载对应的png资源  //对脚本的描述
    // @author       You  //作者,不多解释
    // @include      *yu3.shop*  //适用范围,可以使用通配符“*”。需要注意的是,如果除了本网址之外还需要适用其他网址,需要新添一条@include
    // @grant        none  //第一次开发可以忽略
    // ==/UserScript==
    (function() {
    'use strict';
    // Your code here...
    
    // 在这儿就可以放自己的JS代码了。
    
    //放一个alert('Hello World'); 试试?
    
    })();

    初步了解油猴脚本之后我们分析自己的任务:

     那个网页有多个资源框,对应HTML就是多个表单,表单中有自己需要的资源ID。

    所以我要做的事就是:

    1.  获取当前网页中的所有资源表单

    2.  在当前网页的表单中嵌入一个按钮

    3.  点击该按钮,将该按钮所在表单传入JS函数中

    4.  JS获取表单中的资源ID,并拼接成自己需要的URL

    5.  根据该URL下载资源

    所以一步步的来,

    首先获取当前网页中的所有表单:

    var obj = document.getElementsByName("download");
    

    第二步:

    定义按钮的HTML代码

        var buttonText = '<input type = "button" value = "Download" style="color: #7ED321" onClick="window.execute(this.form);"/>';
        var div = document.createElement("div");
        div.innerHTML = buttonText;
    

      

    这个onClick就是按钮的点击方法,这里面有两个坑我们需要强烈关注。

    1. 为什么使用“window.execute(this.form)”而不是execute(this.form)。如果不使用“window.execute(this.form)”而使用“execute(this.form)” 我们会报 “execute() is not defined” 的错误。原因在油猴脚本的github项目中有描述,我在此引用一下:

    在脚本中定义函数function abc(){ alert("helloWorld"); },注入onclick事件<a id="a" onclick="abc();">HelloWorld</a>。 爆出函数未定义的错误Function is not defined。 在mozillazine了解到Tampermonkey的js脚本是在sandbox中的,在html中访问不到。 使用下面的例子可以完成这个功能

    unsafeWindow.abc = function(msg) {
      alert(msg);
    };
    document.getElementById("a").onclick = "window.abc('helloWorld')";

    2. 为什么使用"this.form" 而不是 "this" 传递参数。这是因为"this"传递的是这个按钮所在标签的本身,而我们要的是这个按钮所在表单。所以使用 "this.form" 

    第三步:

    在所有的资源框中嵌入我们已经写好的下载按钮。

    这一步很简单,遍历就行:

        for(var v of obj){
            v.appendChild(div.cloneNode(true));
        }

    这一步需要注意一个坑。为什么我们使用

     v.appendChild(div.cloneNode(true));

    而非

     v.appendChild(div);

    这是因为,如果我们直接appendChild "div" 这个元素那么这个按钮只会在最后一个资源框生效,所以为了保证按钮能嵌入到所有资源框中,需要使用“div.cloneNode(true)”

    接下来写JS函数,获取表单中我们需要的资源ID,并拼接成URL

        window.execute = function(form){
             var path = form.path_image.getAttribute('value');
         var url = 'http://www.yu3.shop/browse.php'+path+'&b=21&f=norefer' download(url); }

    这一步有一个坑需要注意一下,form.path_image.getAttribute('value')。其中form是传进来的表单,“path_image”是表单中资源所在标签的名字 name = "path_image" 表单中无法直接通过“.value”的形式获取该标签的值,所以使用“.getAttribute('value')”的方式。

    拼接好了url,传给下载函数:

        function download(url){
            var eleLink = document.createElement('a');
            eleLink.download = url;
            eleLink.style.display = 'none';
    // // 字符内容转变成blob地址
            eleLink.href = url;
    // // 触发点击
            document.body.appendChild(eleLink);
            eleLink.click();
    // // 然后移除
            document.body.removeChild(eleLink);
        }

    这部分代码是直接百度的,是我测试的好几个下载代码中比较好的一个,没遇到什么坑,也就不说了。

    至此,一个油猴脚本完成了。

    总计耗时6个小时左右。其中第二步的那两个坑至少耗费了我3个小时,最后谷歌到官方文档才解决,果然遇事不决还是应该多看官方文档啊。

    万事开头难,把第二步那两个坑解决之后后面的还是很轻松的。

    挺充实的一天。

     最后上完整代码

    // ==UserScript==
    // @name         ScriptName
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  用于在yu3.shop代理打开的Illution 网站下载对应的png资源
    // @author       You
    // @include      *yu3.shop*
    // @grant        none
    // ==/UserScript==
    
    (function() {
        'use strict';
        // Your code here...
        var obj = document.getElementsByName("download");
        var buttonText = '<input type = "button" value = "Download" style="color: #7ED321" onClick="window.execute(this.form);"/>';
        var div = document.createElement("div");
        div.innerHTML = buttonText;
        console.log(obj.length);
        for(var v of obj){
            v.appendChild(div.cloneNode(true));
        }
    
    
     //   });
    
        window.execute = function(form){
             var path = form.path_image.getAttribute('value');
         //   console.log(path);
            var name = path.split("/");
            var url = 'http://www.yu3.shop/browse.php'+path+'&b=21&f=norefer'
            download(url);
        }
        function download(url){
            var eleLink = document.createElement('a');
            eleLink.download = url;
            eleLink.style.display = 'none';
    // // 字符内容转变成blob地址
            eleLink.href = url;
    // // 触发点击
            document.body.appendChild(eleLink);
            eleLink.click();
    // // 然后移除
            document.body.removeChild(eleLink);
        }
    
    })();
  • 相关阅读:
    SAP C4C OBN(Object Based Navigation)不能工作的原因分析
    使用SAP C4C自定义BO association创建动态下拉列表
    如何使用SAP HANA Studio的PlanViz分析CDS view性能问题
    如何使用jMeter测试SAP OData服务并发访问时的性能
    OData服务在SAP CRM,Cloud for Customer和S/4HANA上的实现比较
    SAP UI5和Vue的数据双向绑定实现原理比较
    在SAP WebClient UI里显示倒数计时的UI
    【年度重磅】2020华为云社区年度技术精选合集,700页+免费下载!
    面试必问:如何实现Redis分布式锁
    聊聊架构模式的变迁:从分层架构到微服务架构
  • 原文地址:https://www.cnblogs.com/contixue/p/10924885.html
Copyright © 2011-2022 走看看