几个常用音乐平台专辑曲目列表生成 Grab song list information from some websites
// ==UserScript==
// @name XMwiki专辑曲目列表生成
// @version 1.7.3
// @description 几个常用音乐平台专辑曲目列表生成 Grab song list information from some websites
// @author XMAnon
// @icon https://s1.ax1x.com/2020/07/15/UabtVe.jpg
// @match *://www.amazon.com/*
// @match *://www.amazon.de/*
// @match *://www.amazon.fr/*
// @match *://www.amazon.it/*
// @match *://www.amazon.es/*
// @match *://music.apple.com/*
// @match *://open.spotify.com/*
// @match *://www.deezer.com/*
// @match *://music.163.com/*
// @match *://www.discogs.com/*
// the script is mostly inspired by Jeffrey.Deng(https://greasyfork.org/users/129338)复制spotify歌曲名脚本
// Grabbing Info from other sites is almost similar.
// 音乐平台抓取歌曲列表,并生成符合XM格式的歌曲列表(页面2)
// Supported:
// Spotify Album,
// Amazon Free Streaming and MP3 Site (tested on US/DE/IT/FR/ES, other Countries should also work) may not working properly after amazon website update
// Apple Music
// Deezer
// Discogs
// 极地大鹅 (由于抠抠音乐网页版仅显示十首曲目,已注释并已删去网页关联)
// 天空之城 (测试备用)
// To be done:
// Multiple CD case, Bandcamp, MusicBrainz
//
// @namespace https://greasyfork.org/users/666548
// ==/UserScript==
(function() {
'use strict';
// Your code here...
function copyToClipboard(text) {
if (window.clipboardData && window.clipboardData.setData) {
// IE specific code path to prevent textarea being shown while dialog is visible.
return clipboardData.setData("Text", text);
} else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
var textarea = document.createElement("textarea");
textarea.textContent = text;
textarea.style.position = "fixed";// Prevent scrolling to bottom of page in MS Edge.
document.body.appendChild(textarea);
textarea.select();
try {
return document.execCommand("copy");// Security exception may be thrown by some browsers.
} catch (ex) {
console.warn("Copy to clipboard failed.", ex);
return false;
} finally {
document.body.removeChild(textarea);
}
}
}
var song = function(_title, _artist) {
this.title = _title;
this.artist = _artist.replace(/ & | feat. |, /gm,';');
};
function checkSrc(currentUrl){
var getSpotify = function(){};
var getAmazon = function(){};
var getApple = function(){};
var getDeezer = function(){};
var getDiscogs = function(){};
// var getQM = function(){};
var getYM = function(){};
//var getDiscogs = function(){};
//var getDeezer = function(){};
//***************************************** Spotify *********************************************************************
getSpotify = function() {
var nodes = document.querySelectorAll("#main div[data-testid='tracklist-row']");//querySelector('#main .tracklist-container .tracklist').childNodes;//querySelectorAll("div > li > div.tracklist-col.name > div > div");
if (!nodes) {
console.warn("Songs nodes not found!!");
return;
}
var playList = [];
var len = nodes.length;
var charList = '';
for (var i = 0; i < len; i += 1) {
var one = new song(nodes[i].children[1].innerText.split('\n')[0], nodes[i].children[1].innerText.split('\n')[1]);
playList.push(one);
charList = charList + one.title + '【歌手】' + one.artist + '\n';
}
copyToClipboard(charList);
console.log(charList);
}
//***************************************** Amazon *********************************************************************
getAmazon = function(){//Amazon新的流媒体页面没有曲目艺人信息了所以就只抓取了曲目列表 2020.08
//var nodes = document.querySelector("#dmusic_tracklist_content > tbody").getElementsByClassName('a-text-left a-align-center darkenOnHover');//tested on 'amazon.de' unlimited stream page, but now without artists name
var nodes = document.querySelector("#dmusic_tracklist_content > tbody").childNodes;//tested on 'amazon.de' unlimited stream page, but now without artists name
//var headerNode = document.getElementById('dmusic_tracklist_header_box');
var len = nodes.length;
if (!nodes) {
console.warn("nodes not found");
return;}
// else if (len === 0){
// nodes = [headerNode.nextSibling.nextSibling]; //Special Case when it's EP
// len = 1;
// }
var playList = [];
var albumArtist = document.getElementById("ProductInfoArtistLink").innerText;
var charList = '';
for (var i = 0; i < len; i += 2) {
//var rawList = (nodes[i].innerText.split('\t'));
var title = (nodes[i].querySelector(".TitleLink").innerText);
//rawList = rawList.filter(function(e){return e.replace(/\t/gm,"")});
//var one = new song(rawList[1], rawList[2].replace(/ & /gm,';').replace(' feat. ',';').replace(/, /gm,';'));
//var one = new song(rawList[1]);
var one = new song(title,'');
// switch(0){
// case(one.artist.indexOf('\t')):
// one.artist = albumArtist;
// break;
// case(one.artist.indexOf('de ')):
// case(one.artist.indexOf('di ')):
// case(one.artist.indexOf('by ')):
// one.artist = one.artist.substring(3);
// break;
// case(one.artist.indexOf('von ')):
// one.artist = one.artist.substring(4);
// break;
// }
//console.log(rawList);
//console.log(one);
playList.push(one);
//charList = charList + one.title + '【歌手】'+ one.artist + '\n';
charList = charList + one.title + '\n';
}
copyToClipboard(charList);
console.log(charList);
}
//***************************************** Apple *********************************************************************
getApple = function() {
var nodes = document.querySelector('.product-page .header-and-songs-list .songs-list').querySelectorAll(".song");
if (!nodes) {
console.warn("Songs nodes not found!!");
return;
}
var albumArtist = document.querySelector(".product-page .product-creator").innerText.replace(/ & | feat. /gm,';');
var playList = [];
var len = nodes.length;
var charList = '';
var artist = '';
for (var i = 0; i < len; i += 1) {
var title = nodes[i].querySelector(".song-name-wrapper .song-name").innerText;
if (!nodes[i].querySelector(".song-name-wrapper .by-line")){
artist = albumArtist;
}
else{
artist = nodes[i].querySelector(".song-name-wrapper .by-line").innerText}
var one = new song(title, artist);
playList.push(one);
charList = charList + one.title + '【歌手】' + one.artist + '\n';
}
copyToClipboard(charList);
console.log(charList);
}
//***************************************** Deezer *********************************************************************
getDeezer = function() {
var nodes = document.querySelector('.page-content .container .datagrid-container .datagrid').querySelectorAll(".song");
if (!nodes) {
console.warn("Songs nodes not found!!");
return;
}
var albumArtist = document.querySelector('.page-content .container .tnmRk').innerText;//.replace(/ & | feat. /gm,';');
var playList = [];
var len = nodes.length;//曲目数量
var lenLabeled = document.querySelector('.page-content .container .datagrid-container .datagrid').querySelectorAll(".song .datagrid-label-artist").length
var charList = '';
var title = '';
var artist = '';
for (var i = 0; i < len; i += 1) {
title = nodes[i].querySelector(".cell-title span[itemprop]").innerText;
if (!nodes[i].querySelector(".datagrid-label-artist")){//没标艺人,即专辑艺人
artist = albumArtist;}
else{//标了艺人,feat需加上专辑艺人
if(len > lenLabeled){
var coartist = nodes[i].querySelector(".datagrid-label-artist").innerText;
artist = albumArtist + ';' + coartist;
}
else{
artist = nodes[i].querySelector(".datagrid-label-artist").innerText;
}
}
var one = new song(title, artist);
playList.push(one);
charList = charList + one.title + '【歌手】' + one.artist + '\n';
}
copyToClipboard(charList);
console.log(charList);
}
//***************************************** QM *********************************************************************垃圾抠抠音乐网页版专辑曲目显示不全 2020.9
// getQM = function() {
// var nodes = document.querySelector('#song_box').querySelectorAll('li');
// if (!nodes) {
// console.warn("Songs nodes not found!!");
// return;
// }
// var playList = [];
// var len = nodes.length;//曲目数量
// var charList = '';
// var title = '';
// var artist = '';
// for (var i = 0; i < len; i += 1) {
// title = nodes[i].querySelector('.songlist__songname .songlist__songname_txt a').title;
// var arNodes = nodes[i].querySelector('.songlist__artist').querySelectorAll('.singer_name');
// if (!arNodes) {
// console.warn("Artists nodes not found!!");
// return;
// }
// else{
// artist = arNodes[0].title;
// if(arNodes.length > 1){
// for (var j = 1; j < arNodes.length; j ++){
// artist = artist + ';' + arNodes[j].title;
// }
// }
// var one = new song(title, artist);
// playList.push(one);
// charList = charList + one.title + '【歌手】' + one.artist + '\n';
// }
// }
// copyToClipboard(charList);
// console.log(charList);
// }
//***************************************** YM *********************************************************************云村和抠抠音乐网页版基本一样,不写白不写,万一有人需要 2020.09
getYM = function() {
var tryNode = document.querySelector('#song-list-pre-cache tbody');
var nodes = [];
if (!tryNode) {//Body node not found
console.warn("Iframe exist!?");
nodes = document.querySelector('#g_iframe').contentDocument.querySelector('#song-list-pre-cache tbody').childNodes
if (!nodes) {
console.warn("No songs found!! ");
return;
}
}
else{
nodes = tryNode.childNodes;
if (!nodes) {
console.warn("No songs found!! ");
return;
}
}
var playList = [];
var len = nodes.length;//曲目数量
var charList = '';
var title = '';
var artist = '';
for (var i = 0; i < len; i += 1) {
title = nodes[i].querySelector('td .txt a b').title;
artist = nodes[i].querySelector('td .text span').title.replace(/\//gm,';');
var one = new song(title, artist);
playList.push(one);
charList = charList + one.title + '【歌手】' + one.artist + '\n';
}
copyToClipboard(charList);
console.log(charList);
}
//var getBandCamp = function(){}
//var getMusicBrain = function(){}
//***************************************** Discogs *********************************************************************
getDiscogs = function(){//Discogs格式情况有点多,后面慢慢补,目前列出了以下几种情况,带Blockquote的查找"Featuring"关键词添加曲目艺人
// tested album: blockquote featuring tracklist_track_artists tracklist_track_title
// no song artits https://www.discogs.com/Taylor-Swift-Folklore/master/1777815 x x
// x detail(complicated) song artists https://www.discogs.com/Clueso-Handgep%C3%A4ck-I/release/12446518 x x
// x detail(complicated) song artists https://www.discogs.com/Oonagh-Oonagh/release/5542798 x x
// EP no song artists https://www.discogs.com/Oonagh-G%C3%A4a/release/5686699 x
// Complition no song artists, with feat. https://www.discogs.com/Oonagh-Best-Of/release/15751583 x x x
// Various Artists 1 https://www.discogs.com/Leikf%C3%A9lag-%C3%8Dslands-Leikf%C3%A9lag-Reykjav%C3%ADkur-Stone-Free/release/2663095 x x
// x no song artist https://www.discogs.com/Lord-Finesse-The-Awakening/release/15752829 x x
var nodes = document.querySelector("#tracklist .playlist").querySelectorAll('.tracklist_track.track');//
var len = nodes.length;
if (!nodes) {
console.warn("nodes not found");
return;}
var aaNodes = document.querySelector("#profile_title").querySelectorAll('span[title]');
if (!aaNodes) {
console.warn("Error! Album artists not found!");//hope wont happen
return;}
else{
var albumArtist = aaNodes[0].title.split(' (')[0].replace('*','');
for(var j = 1 ; j < aaNodes.length ; j++){
albumArtist = albumArtist + ';' + aaNodes[j].title.split(' (')[0].replace('*','');
}//艺人从title取,Discogs重复艺人会有数字编码,截去括号和同名星号
}
console.log('Album Artists:' + albumArtist);//test album artists
var playList = [];
var charList = '';
var title = '';
var artist = '';
for (var i = 0; i < len; i += 1)
{
title = nodes[i].querySelector('.tracklist_track_title span').innerText;
var miniArtistNodes = nodes[i].querySelector('.tracklist_track_artists');
var getBlockQuoteNodes = nodes[i].querySelector('blockquote');//貌似只在没有艺人小列表的情况下出现
if(!miniArtistNodes){//没找到艺人小列表
if(!getBlockQuoteNodes){
artist = albumArtist;//没有注释即专辑艺人
}
else{
getBlockQuoteNodes = getBlockQuoteNodes.childNodes;//有注释需专辑艺人+feat艺人
artist = albumArtist;
for(j = 0; j< getBlockQuoteNodes.length; j++){//遍历blockquote
if(getBlockQuoteNodes[j].innerText.indexOf('Featuring') > -1){
var featArtist = getBlockQuoteNodes[j].querySelectorAll('a[href]');//不确定将来会不会出现feat的艺人没有子链接的情况,可能会漏
if(featArtist){
for(var k = 0; k<featArtist.length ; k++){
artist = artist + ';' + featArtist[k].innerText.split(' (')[0].replace('*','');//截去括号加数字编号和同名星号
}
}
}
}
}
}
else{
miniArtistNodes = miniArtistNodes.querySelectorAll('.tracklist_track_artists a[href]');//有艺人小列表即mini_playlist_track_has_artist
artist = miniArtistNodes[0].innerText.split(' (')[0].replace('*','');//截去括号加数字编号和同名星号
for(j = 1 ; j < miniArtistNodes.length ; j++){
artist = artist + ';' + miniArtistNodes[j].innerText.split(' (')[0].replace('*','');//截去括号加数字编号和同名星号
}//艺人从title取,Discogs重复艺人会有数字编码,截去括号
}
var one = new song(title, artist);
playList.push(one);
charList = charList + one.title + '【歌手】' + one.artist + '\n';
}
copyToClipboard(charList);
console.log(charList);
}
//*********************************************************************************************************************
switch(true){
case (currentUrl.indexOf('open.spotify.com') > -1):
getSpotify();
break;
case (currentUrl.indexOf('www.amazon') > -1):
getAmazon();
break;
case (currentUrl.indexOf('music.apple.com') > -1):
getApple();
break;
case (currentUrl.indexOf('www.deezer.com') > -1):
getDeezer();
break;
// case (currentUrl.indexOf('y.qq.com') > -1 && currentUrl.indexOf('album') > -1):
// getQM();
// break;
case (currentUrl.indexOf('music.163.com') > -1 && currentUrl.indexOf('album') > -1):
getYM();
break;
//case (currentUrl.indexOf('bandcamp') > -1):
case (currentUrl.indexOf('discogs.com') > -1):
getDiscogs();
break;
default:
console.warn('Host not matching');
}
}
//**************打印下键盘事件的event对象**********
// document.onkeydown = function (oEvent) {
// console.log(oEvent);}
// ************************************************
document.onkeydown = function(oEvent) {//快捷键Shift + C 触发命令
oEvent = oEvent || window.oEvent;
//获取键盘的keyCode值
var nKeyCode = oEvent.keyCode // || oEvent.which || oEvent.charCode;
//获取shift 键对应的事件属性
var bShiftKeyCode = oEvent.shiftKey //|| oEvent.metaKey;
if(nKeyCode == 67 && bShiftKeyCode) {//快捷键 shift + c : shift(shiftKey) c(keyCode = 67; which = 67; charCode = 0 ) x(keyCode = 88;which = 88; charCode = 0 )
//doSomeThing...
//alert('you punched shift + c');
var currentUrl = window.location.href;
checkSrc(currentUrl);//check source and get song list
}
}
})();