🏠 Home 

网易云音乐列表导出

导出当前页网易云音乐列表为文本

// ==UserScript==
// @name         网易云音乐列表导出
// @namespace    undefined
// @version      0.0.4
// @description  导出当前页网易云音乐列表为文本
// @author       allen smith
// @match        *://music.163.com/*
// @require      https://cdn.bootcss.com/clipboard.js/1.7.1/clipboard.js
// @require      https://cdn.bootcdn.net/ajax/libs/Sortable/1.15.0/Sortable.min.js
// @run-at       document-end
// @grant        none
// ==/UserScript==
(function () {
'use strict';
// 检测页面
let htm = document.getElementsByClassName('f-oh');
if(htm.length === 0){
return;
}
// 创建dom节点
function createDocument(txt) {
const template = `<div class='childdom'>${txt}</div>`;
let doc = new DOMParser().parseFromString(template, 'text/html');
let div = doc.querySelector('.childdom');
return div;
}
// 检测文档变动
let doc = document.getElementById('g_mymusic');
let _body = document.body;
let clipboard, btn, spli, interId, waitTimeoutId, wait ;
let ckdiv;
let check1, check2, check3, check4, check5;
let sortdiv;
doc.addEventListener('DOMSubtreeModified', function () {
//查找列表动画
wait = document.getElementById('wait-animation');
if(wait) _body.removeChild(wait);
wait = document.createElement("span");
wait.id = 'wait-animation';
wait.setAttribute('style', 'display:inline-block;position:absolute;right:50px;top:100px;padding:3px 5px;border:1px solid lightgray;background-color:white;color:black;border-radius:5px;font-size:14px;');
_body.appendChild(wait);
wait.innerHTML = '导出:没有合适的列表';
//检测列表
let list = document.getElementsByClassName('m-table')[0];
if (!list) {
btn = document.getElementById('export-btn');
spli = document.getElementById('export-spli');
if(btn) _body.removeChild(btn);
if(spli) _body.removeChild(spli);
return;
}
_body.removeChild(wait);
//创建按钮
btn = null;
spli = null;
btn = document.getElementById('export-btn');
spli = document.getElementById('export-spli');
if (!spli) {
spli = document.createElement("input");
spli.id = 'export-spli';
spli.className = 'export-spli';
spli.setAttribute('placeholder','自定义分隔符(默认 -- )');
spli.setAttribute('style', 'display:inline-block;position:absolute;right:50px;top:100px;padding:3px 5px;border:1px solid lightgray;background-color:white;color:black;border-radius:5px;font-size:14px;');
_body.appendChild(spli);
}
if (!btn) {
btn = document.createElement("button");
btn.id = 'export-btn';
btn.className = 'export-btn';
btn.innerText = '导出列表';
btn.setAttribute('style', 'display:inline-block;position:absolute;right:50px;top:229px;padding:3px 5px;border:1px solid lightgray;background-color:white;color:black;border-radius:5px;font-size:14px;');
_body.appendChild(btn);
}
// 选择列
if(!ckdiv){
ckdiv = document.createElement("div");
ckdiv.id = 'ckdiv';
ckdiv.className = 'export-ck';
ckdiv.setAttribute('style', 'display:inline-block;position:absolute;right:50px;top:128px;padding:3px 5px;border:1px solid lightgray;background-color:white;color:black;border-radius:5px;font-size:14px;');
_body.appendChild(ckdiv);
}
// 排序
if(!sortdiv){
// sortdiv = document.createElement("div");
// sortdiv.id = 'sortdiv';
// sortdiv.className = 'sortdiv';
// sortdiv.setAttribute('style', 'display:inline-block;position:absolute;right:50px;top:156px;padding:3px 5px;border:1px solid lightgray;background-color:white;color:black;border-radius:5px;font-size:14px;');
let divstr = `<div id="sortdivbox" style="display:inline-block;position:absolute;right:50px;top:159px;padding:3px 5px;border:1px solid lightgray;background-color:white;color:black;border-radius:5px;font-size:14px;"><div>拖动以排序</div><div id="sortdiv" style="margin:10px 0px;cursor:pointer;"><span style="margin:0 4px;padding:4px 8px;border-radius:3px;border:1px solid lightgray">歌名</span><span style="margin:0 4px;padding:4px 8px;border-radius:3px;border:1px solid lightgray">歌手</span><span style="margin:0 4px;padding:4px 8px;border-radius:3px;border:1px solid lightgray">专辑</span><span style="margin:0 4px;padding:4px 8px;border-radius:3px;border:1px solid lightgray">时长</span><span style="margin:0 4px;padding:4px 8px;border-radius:3px;border:1px solid lightgray">链接</span></div></div>`
_body.appendChild(createDocument(divstr));
sortdiv = new Sortable(document.querySelector('#sortdiv'))
}
let ckbuilder = function(id, label, uncheck, readonly){
let tmpid = 'ck_' + id;
let ckbox = document.createElement("input");
ckbox.id = tmpid
ckbox.setAttribute('type', 'checkbox');
ckbox.setAttribute('style', 'vertical-align: middle;margin-top: -2px;');
if(!uncheck) ckbox.checked = true;
if(!!readonly) ckbox.setAttribute("disabled", "disabled");
ckdiv.appendChild(ckbox);
let ckspn = document.createElement("label");
ckspn.setAttribute('for', tmpid);
ckspn.innerHTML = ' ' + label;
ckdiv.appendChild(ckspn);
return ckbox;
}
if(!check1){
check1 = ckbuilder("ck01","歌名 ", false, true);
}
if(!check2){
check2 = ckbuilder("ck02","歌手 ");
}
if(!check3){
check3 = ckbuilder("ck03","专辑 ", true);
}
if(!check4){
check4 = ckbuilder("ck04","时长 ", true);
}
if(!check5){
check5 = ckbuilder("ck05","链接", true);
}
//创建剪贴板
if (clipboard) clipboard.destroy();
clipboard = new Clipboard('.export-btn', {
text: function (trigger) {
//导出列表
btn.innerText = '正在导出 ...';
let r###lt = '';
let listBody = list.getElementsByTagName('tbody')[0];
let rows = listBody.getElementsByTagName('tr');
for (let i = 0; i < rows.length; i++) {
let ele = rows[i];
let cells = ele.getElementsByTagName('td');
let name = cells[1].getElementsByTagName('b')[0].getAttribute('title').replace(/<div class="soil">[\s\S\n]*?<\/div>/g, "").replace(/&nbsp;/g, " ").replace(/&amp;/g, "&");
let link = `https://music.163.com/#${cells[1].getElementsByTagName('a')[0].getAttribute('href')}`
let time = cells[2].querySelector('.u-dur').innerText;
let artist = cells[3].getElementsByTagName('span')[0].getAttribute('title').replace(/<div class="soil">[\s\S\n]*?<\/div>/g, "").replace(/&nbsp;/g, " ").replace(/&amp;/g, "&");
let album = cells[4].getElementsByTagName('a')[0].getAttribute('title').replace(/<div class="soil">[\s\S\n]*?<\/div>/g, "").replace(/&nbsp;/g, " ").replace(/&amp;/g, "&");
let spliChar = spli.value;
if(!spliChar) spliChar = ' -- ';
let isFirst = true;
document.querySelectorAll('#sortdiv span').forEach(item=>{
let type = item.innerText;
let tempSplit;
if(isFirst){
tempSplit = ()=> {isFirst = false; return "";}
}else {
tempSplit = ()=> spliChar;
}
switch(type){
case "歌名":
r###lt += tempSplit() + name;
break;
case "歌手":
if(check2.checked){
r###lt += tempSplit() + artist;
}
break;
case "专辑":
if(check3.checked){
r###lt += tempSplit() + album;
}
break;
case "时长":
if(check4.checked){
r###lt += tempSplit() + time;
}
break;
case "链接":
if(check5.checked){
r###lt += tempSplit() + link;
}
break;
}
})
r###lt += '\r\n';
}
//提示动画
btn.innerText = '已复制到剪贴板 =';
let count = 6;
clearInterval(interId);
interId = setInterval(function () {
count--;
if (count > 0){
btn.innerText = '已复制到剪贴板 ' + waitAnimationChar(count);
}
else{
btn.innerText = '导出列表';
clearInterval(interId);
}
}, 300);
//输出到控制台
console.log(r###lt);
//输出到剪贴板
trigger.setAttribute('aria-label', r###lt);
return trigger.getAttribute('aria-label');
}
});
});
//字符动画
let waitAnimationChar = function(n){
let temp = n % 3;
if(temp === 0) return '#';
else if(temp == 1) return '$';
else if(temp == 2) return '+';
};
})();