前言

  我想在 5sing 上下载一首歌,但是下载又需要登录,而我以前注册的账号连一个字母都想不起来了,于是就只能通过官方的API来下载了。为了一劳永逸,我决定研究一下油猴脚本,用于实现在歌曲页面里能够绕过登录并且一键下载的功能。

油猴脚本

  油猴,英文Tampermonkey,又名Greasemonkey,是一款用户脚本管理器,ChromeFirefox均支持,其原理有点像Windows编程里的hook,它的可自定义性非常高,能给用户带来无限可能。

  新建一个油猴脚本,默认内容如下,无需过多配置,填写好UserScript就可以开始编写了。

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        http://*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Your code here...
})();

流程

  我是第一次写油猴脚本,也没有系统学习过JS,得亏天下编程语言万变不离其宗,凭着“语感”一边摸索一边“借鉴”,居然也完成了。

  不会画流程图,大概是这样,具体看代码:

2.png

获取歌曲ID及类型

  ID和歌曲类型可以在歌曲页面网址上直接获得,例如:http://5sing.kugou.com/fc/17237123.htmlfc就是类型,表示此歌曲是翻唱歌曲,同理yc则是原唱歌曲,17237123就是歌曲ID了。

var id = window.location.href.split('/')[4].split(".")[0];
var type = window.location.href.split('/')[3].split(".")[0];

获取歌曲下载链接

  向接口http://service.5sing.kugou.com/song/getsongurl?&songid=[id]&songtype=[fc]发送GET请求,其中的两个参数songidsongtype的值,上面已讲,不再赘述。成功后会返回一组Json,里边有各种音质、歌曲MD5等等信息,反序列化一下提取对应音质的下载链接即可。

var url = 'http://service.5sing.kugou.com/song/getsongurl?&songid=' + id + '&songtype='+type;
GM_xmlhttpRequest({
    method: "GET",
    url: url,
    onload: function (res) {
        if (res.status == 200) {
            var text = res.responseText;
            var ret = jQuery.parseJSON(text)
        }
    }
}

添加下载事件

var oDivNode = document.getElementById("func_Down");
oDivNode.addEventListener("click",function(){
    down_music(music_url,id+".mp3");
    $('.new_login_bg').remove();
});

难点

  由于我不知道的某个原因,对于视频、音频、文本等等文件直链访问并不会触发下载,而是直接在浏览器中预览,这就很烦,尝试了几个方法,貌似只能创建blob对象来下载。

  可能对前端大佬来说这不是什么难点,但对我这种半桶水的来说可能就难一点了。

function down_music(url, name) {
    let that = this
    let oReq = new XMLHttpRequest();
    oReq.open("GET", url, true);
    oReq.responseType = "blob";
    //oReq.withCredentials = true;//如果跨域
    oReq.onload = function (oEvent) {
        let content = oReq.response;
        let elink = document.createElement('a');
        elink.download = name;
        elink.style.display = 'none';
        let blob = new Blob([content])
        elink.href = URL.createObjectURL(blob);
        document.body.appendChild(elink);
        elink.click();
        document.body.removeChild(elink);
    };
    oReq.send();
}

效果

  出现跨域提醒时,点击总是允许此域名即可,以后使用时就不会弹出了。

1.gif

如果觉得我的文章对您有用,请我喝一杯咖啡吧~