(Diperbarui 2016-05-09, lebih kuat dari jawaban teratas saat ini)
Jika Anda hanya perlu menyimpan beberapa daftar putar, Anda dapat menggunakan cuplikan Javascript di bawah ini. Cuplikan ini dapat menyimpan setiap daftar seperti yang ditunjukkan pada halaman web, sehingga juga berfungsi untuk semua lagu / album / tampilan pustaka artis. Saya telah mendaftarkan dua alternatif lain di akhir jawaban ini.
Buka: https://play.google.com/music/listen#/all (atau daftar putar Anda)
Buka konsol pengembang (F12 untuk Chrome). Tempel kode di bawah ini ke konsol.
Semua lagu yang tergores disimpan di allsongs
objek dan versi teks dari daftar disalin ke clipboard. Saya sarankan menjalankan
songsToText("all",true)
setelah itu untuk mendapatkan informasi CSV lengkap. Jalankan copy(outText)
secara manual jika penyalinan clipboard tidak berfungsi pada percobaan pertama.
Kode (versi terbaru 10 Mei 2016, Rev 30):
var allsongs = []
var outText = "";
var songsToText = function(style, csv, likedonly){
if (style === undefined){
console.log("style is undefined.");
return;
}
var csv = csv || false; // defaults to false
var likedonly = likedonly || false; // defaults to false
if (likedonly) {
console.log("Only selecting liked songs");
}
if (style == "all" && !csv){
console.log("Duration, ratings, and playcount will only be exported with the CSV flag");
}
outText = "";
if (csv) {
if (style == "all") {
//extra line
outText = "artist,album,title,duration,playcount,rating,rating_interpretation" + "\n";
} else if (style == "artist") {
} else if (style == "artistsong") {
} else if (style == "artistalbum") {
} else if (style == "artistalbumsong") {
} else {
console.log("style not defined");
}
}
var numEntries = 0;
var seen = {};
for (var i = 0; i < allsongs.length; i++) {
var curr = "";
var properTitle = allsongs[i].title.replace(/[\n\r!]/g, '').trim();
if (!likedonly || (likedonly && allsongs[i].rating >= 5)){
if (csv) {
if (style == "all") {
//extra line
curr += '"' + allsongs[i].artist.replace(/"/g, '""').trim() + '"' + ",";
curr += '"' + allsongs[i].album.replace(/"/g, '""').trim() + '"' + ",";
curr += '"' + properTitle.replace(/"/g, '""').trim() + '"' + ",";
curr += '"' + allsongs[i].duration.replace(/"/g, '""').trim() + '"' + ",";
curr += '"' + allsongs[i].playcount.replace(/"/g, '""').trim() + '"' + ",";
curr += '"' + allsongs[i].rating.replace(/"/g, '""').trim() + '"' + ",";
curr += '"' + allsongs[i].rating_interpretation.replace(/"/g, '""').trim() + '"';
} else if (style == "artist") {
curr += '"' + allsongs[i].artist.replace(/"/g, '""').trim() + '"';
} else if (style == "artistsong") {
curr += '"' + allsongs[i].artist.replace(/"/g, '""').trim() + '"' + ",";
curr += '"' + properTitle.replace(/"/g, '""').trim() + '"';
} else if (style == "artistalbum") {
curr += '"' + allsongs[i].artist.replace(/"/g, '""').trim() + '"' + ",";
curr += '"' + allsongs[i].album.replace(/"/g, '""').trim() + '"';
} else if (style == "artistalbumsong") {
curr += '"' + allsongs[i].artist.replace(/"/g, '""').trim() + '"' + ",";
curr += '"' + allsongs[i].album.replace(/"/g, '""').trim() + '"' + ",";
curr += '"' + properTitle.replace(/"/g, '""').trim() + '"';
} else {
console.log("style not defined");
}
} else {
if (style == "all"){
curr = allsongs[i].artist + " - " + allsongs[i].album + " - " + properTitle + " [[playcount: " + allsongs[i].playcount + ", rating: " + allsongs[i].rating_interpretation + "]]" ;
} else if (style == "artist"){
curr = allsongs[i].artist;
} else if (style == "artistalbum"){
curr = allsongs[i].artist + " - " + allsongs[i].album;
} else if (style == "artistsong"){
curr = allsongs[i].artist + " - " + properTitle;
} else if (style == "artistalbumsong"){
curr = allsongs[i].artist + " - " + allsongs[i].album + " - " + properTitle;
} else {
console.log("style not defined");
}
}
if (!seen.hasOwnProperty(curr)){ // hashset
outText = outText + curr + "\n";
numEntries++;
seen[curr] = true;
} else {
//console.log("Skipping (duplicate) " + curr);
}
}
}
console.log("=============================================================");
console.log(outText);
console.log("=============================================================");
try {
copy(outText);
console.log("copy(outText) to clipboard succeeded.");
} catch (e) {
console.log(e);
console.log("copy(outText) to clipboard failed, please type copy(outText) on the console or copy the log output above.");
}
console.log("Done! " + numEntries + " lines in output. Used " + numEntries + " unique entries out of " + allsongs.length + ".");
};
var scrapeSongs = function(){
var intervalms = 1; //in ms
var timeoutms = 3000; //in ms
var retries = timeoutms / intervalms;
var total = [];
var seen = {};
var topId = "";
document.querySelector("#mainContainer").scrollTop = 0; //scroll to top
var interval = setInterval(function(){
var songs = document.querySelectorAll("table.song-table tbody tr.song-row");
if (songs.length > 0) {
// detect order
var colNames = {
index: -1,
title: -1,
duration: -1,
artist: -1,
album: -1,
playcount: -1,
rating: -1
};
for (var i = 0; i < songs[0].childNodes.length; i++) {
colNames.index = songs[0].childNodes[i].getAttribute("data-col") == "index" ? i : colNames.index;
colNames.title = songs[0].childNodes[i].getAttribute("data-col") == "title" ? i : colNames.title;
colNames.duration = songs[0].childNodes[i].getAttribute("data-col") == "duration" ? i : colNames.duration;
colNames.artist = songs[0].childNodes[i].getAttribute("data-col") == "artist" ? i : colNames.artist;
colNames.album = songs[0].childNodes[i].getAttribute("data-col") == "album" ? i : colNames.album;
colNames.playcount = songs[0].childNodes[i].getAttribute("data-col") == "play-count" ? i : colNames.playcount;
colNames.rating = songs[0].childNodes[i].getAttribute("data-col") == "rating" ? i : colNames.rating;
}
// check if page has updated/scrolled
var currId = songs[0].getAttribute("data-id");
if (currId == topId){ // page has not yet changed
retries--;
scrollDiv = document.querySelector("#mainContainer");
isAtBottom = scrollDiv.scrollTop == (scrollDiv.scrollHeight - scrollDiv.offsetHeight)
if (isAtBottom || retries <= 0) {
clearInterval(interval); //done
allsongs = total;
console.log("Got " + total.length + " songs and stored them in the allsongs variable.");
console.log("Calling songsToText with style all, csv flag true, likedonly false: songsToText(\"all\", false).");
songsToText("artistalbumsong", false, false);
}
} else {
retries = timeoutms / intervalms;
topId = currId;
// read page
for (var i = 0; i < songs.length; i++) {
var curr = {
dataid: songs[i].getAttribute("data-id"),
index: (colNames.index != -1 ? songs[i].childNodes[colNames.index].textContent : ""),
title: (colNames.title != -1 ? songs[i].childNodes[colNames.title].textContent : ""),
duration: (colNames.duration != -1 ? songs[i].childNodes[colNames.duration].textContent : ""),
artist: (colNames.artist != -1 ? songs[i].childNodes[colNames.artist].textContent : ""),
album: (colNames.album != -1 ? songs[i].childNodes[colNames.album].textContent : ""),
playcount: (colNames.playcount != -1 ? songs[i].childNodes[colNames.playcount].textContent : ""),
rating: (colNames.rating != -1 ? songs[i].childNodes[colNames.rating].getAttribute("data-rating") : ""),
rating_interpretation: "",
}
if(curr.rating == "undefined") {
curr.rating_interpretation = "never-rated"
}
if(curr.rating == "0") {
curr.rating_interpretation = "not-rated"
}
if(curr.rating == "1") {
curr.rating_interpretation = "thumbs-down"
}
if(curr.rating == "5") {
curr.rating_interpretation = "thumbs-up"
}
if (!seen.hasOwnProperty(curr.dataid)){ // hashset
total.push(curr);
seen[curr.dataid] = true;
}
}
songs[songs.length-1].scrollIntoView(true); // go to next page
}
}
}, intervalms);
};
scrapeSongs();
// for the full CSV version you can now call songsToText("all", true);
Kode terbaru tentang Github (Gist) di sini: https://gist.github.com/jmiserez/c9a9a0f41e867e5ebb75
Jika Anda ingin output dalam format teks, dapat memanggil fungsi songsToText (). Anda dapat memilih gaya, memilih format, dan jika hanya lagu yang disukai / diacungi jempol yang akan diekspor. Daftar yang dihasilkan kemudian akan ditempelkan ke clipboard. Gaya yang all
, artist
, artistalbum
, artistsong
,
artistalbumsong
. CSV akan menghasilkan file CSV dan dapat ditinggalkan (default ke false). Likedonly dapat ditinggalkan (default ke false) atau disetel ke true, dan akan memfilter semua lagu dengan peringkat lebih besar atau sama dengan 5. Misalnya:
songsToText("all",true,false)
akan mengekspor semua lagu dalam format csv.
songsToText("all",true,true)
hanya akan mengekspor lagu yang disukai dalam format csv.
songsToText("artistsong",false,false)
akan mengekspor semua lagu sebagai teks.
Anda kemudian dapat menempelkan data di mana saja Anda suka, misalnya http://www.ivyishere.org/ jika Anda ingin menambahkan lagu atau album ke akun Spotify Anda. Untuk membuat Ivy mengenali album lengkap, gunakan gaya "artistalbum". Untuk lagu, gunakan gaya "seniman".
Tentang cuplikan:
Ini didasarkan pada jawaban asli Michael Smith, tetapi sedikit lebih kuat. Saya telah melakukan peningkatan berikut:
Bekerja pada daftar putar maupun perpustakaan. Setiap kolom yang hilang diabaikan dan urutannya sudah ditentukan, jadi itu akan berfungsi pada hampir semua daftar lagu di dalam Google Music.
Ia berhenti ketika mencapai bagian bawah (mendeteksi posisi gulir), atau setelah batas waktu yang ditentukan. Batas waktu ada untuk mencegah loop tanpa henti seandainya kode deteksi gulir dimatikan beberapa piksel.
Ini jauh lebih cepat (interval setiap 1 ms), tetapi menunggu jika data tidak siap (hingga batas waktu yang ditentukan, saat ini 3 detik).
Apakah deduplikasi selama operasi dan pada output.
Mengumpulkan peringkat: "tidak terdefinisi" tidak pernah diberi peringkat, "0" tidak diberi peringkat (yaitu sekali dinilai tetapi kemudian dihapus), "1" adalah jempol ke bawah, dan "5" adalah jempol ke atas (disukai).
Selain perbaikan dasar, itu juga memformat teks dengan baik dan menyalinnya ke clipboard. Anda juga bisa mendapatkan data sebagai CSV jika diinginkan, dengan menjalankan songsToText
fungsi ini untuk kedua kalinya.
Alternatif:
Jika Anda memerlukan API Python, periksa proyek Google Music API tidak resmi .
Jika Anda memiliki banyak daftar putar dan ingin mengekspor semuanya dalam sekali jalan, coba eksportir daftar putar gmusic-scripts yang dapat melakukannya (Python, menggunakan proyek API tidak resmi).