In danh sách phát từ Google Play Music


43

Tôi muốn in danh sách các bài hát (với nghệ sĩ, album, xếp hạng và, nếu có thể, số lần phát và thời lượng) từ tài khoản Google Play Music của tôi .

Không có cách dễ dàng để làm điều này từ ứng dụng. Làm màn hình in khi tôi trang qua một danh sách dài các bài hát là không thể thực hiện được.

Tôi sẽ hài lòng với việc xuất dữ liệu sang định dạng chuẩn (văn bản thuần túy, CSV, XML, v.v.) mà tôi có thể tự thao tác.

Bất kỳ đề xuất?


Câu trả lời:


17

Sửa đổi câu trả lời của darkl Liquid , tôi đã đưa ra những điều sau đây cho phép lưu nhiều danh sách phát cùng một lúc .

Hướng dẫn:

  1. Chuyển đến trang Danh sách phát của bạn .
  2. Dán mã JavaScript bên dưới vào bảng điều khiển của bạn.
  3. Bấm vào danh sách phát mà bạn muốn lưu vào văn bản.
  4. Khi ở trên trang danh sách phát, cuộn xuống phía dưới tương đối chậm.
  5. Sau khi bạn cuộn xuống dưới cùng, hãy điều hướng quay lại trang danh sách phát (giống như trong bước 1.) bằng cách sử dụng menu hoặc nút quay lại trình duyệt của bạn.
  6. Lặp lại các bước 3-5 cho tất cả các danh sách phát bạn muốn lưu vào văn bản.
  7. Khi bạn đã thực hiện điều này cho tất cả các danh sách phát bạn muốn lưu vào văn bản, bạn có thể nhập JSON.stringify(tracklistObj, null, '\t')(thay đổi '\t'thành ' 'nếu bạn muốn thụt lề tối thiểu) hoặc tracklistObjnếu bạn chỉ muốn đối tượng JavaScript thao tác theo cách riêng của mình. Nếu bạn muốn nó được sắp xếp, chạy lệnh Object.values(tracklistObj).forEach(a => a.sort()) trước khi gọi JSON.stringifylệnh.

Hãy cẩn thận để không làm mới trang trước khi bạn hoàn thành tất cả những gì bạn muốn làm nếu không bạn sẽ phải khởi động lại từ bước 1.

// Setup
var tracklistObj = {},
    currentPlaylist,
    checkIntervalTime = 100,
    lastTime;

// Process the visible tracks
function getVisibleTracks() {
    var playlist = document.querySelectorAll('.song-table tr.song-row');
    for(var i = 0; i < playlist.length ; i++) { 
        var l = playlist[i];

        var title = l.querySelector('td[data-col="title"] .column-content');
        if(title !== null)
            title = title.textContent;

        var artist = l.querySelector('td[data-col="artist"] .column-content');
        if(artist !== null)
            artist = artist.textContent;

        var duration = l.querySelector('td[data-col="duration"] span');
        if(duration !== null)
            duration = duration.textContent;

        var album = l.querySelector('td[data-col="album"] .column-content');
        if(album !== null)
            album = album.textContent;

        var playCount = l.querySelector('td[data-col="play-count"] span');
        if(playCount !== null)
            playCount = playCount.textContent;

        var rating = l.querySelector('td[data-col="rating"]');
        if(rating !== null)
            rating = rating.textContent;

        // Add it if it doesn't exist already
        if(tracklistObj[currentPlaylist] && !tracklistObj[currentPlaylist].includes(artist + " - " + title)) {
            tracklistObj[currentPlaylist].push(artist + " - " + title);

            if(printTracksToConsole) {
                console.log(artist + ' - ' + title);
            }
        }
    }
}

// Listen for page changes
window.onhashchange = function(e) {
    currentPlaylist = null; 

    var doneLoading = setInterval(function() {
        var playListName = document.querySelector('.gpm-detail-page-header h2[slot="title"]');
        if(playListName != null) {
            currentPlaylist = playListName.innerText;
            if(tracklistObj[currentPlaylist] === undefined) {
                tracklistObj[currentPlaylist] = [];
            }

            console.log("===================================");
            console.log("Adding to playlist " + currentPlaylist);

            getVisibleTracks();

            clearInterval(doneLoading);
        }
    }, 100);

}

// Check for new tracks every so often
setInterval(function() {
    getVisibleTracks();
}, checkIntervalTime);

// Whether or not to print the tracks obtained to the console
var printTracksToConsole = false;

Bạn cũng có thể in ra tên bài hát ra cửa sổ Console khi bạn đi bằng cách thay đổi printTracksToConsoleđể true(bạn nên làm điều này trước khi Bước 3).

Lưu ý rằng bạn có thể bỏ qua tất cả các lỗi GET và POST trong bảng điều khiển (những lỗi này được tạo bởi chính Play Music, không phải tập lệnh này).

Cũng lưu ý rằng hiện tại của thiết lập chỉ để cung cấp cho Artist - Track name, nhưng bạn có thể dễ dàng chỉnh sửa dòng có tracklistObj[currentPlaylist].push(artist + " - " + title);với album, playCount, duration, hay rating, và / hoặc bất cứ định dạng bạn muốn (bao gồm cả định dạng CSV nếu bạn vì vậy hãy).

Ví dụ đầu ra (tất cả danh sách phát Google Play tôi hiện có) với cài đặt mặc định. Tổng cộng mất khoảng 5 phút để điều hướng đến từng trong số 32 danh sách phát, cuộn xuống và sau đó chuyển đổi kết quả thành văn bản.

PS Bạn có thể thích sử dụng một trang web mà tôi tìm thấy có tên Tune My Music để tạo danh sách phát YouTube (nhưng YouTube hạn chế tạo danh sách phát xuống còn 10 ngày) từ đầu ra để bạn bè của bạn có thể nghe Danh sách phát Google của bạn. Nếu bạn làm điều này, có lẽ bạn muốn sử dụng một cái gì đó như TextMechanic để xóa các trích dẫn và .mp3khỏi danh sách xuất ra.


1
Nếu chỉ có một cách tốt hơn để làm điều này hơn là dán JavaScript trong bảng điều khiển. (Tôi cũng có một chút trục trặc kể từ khi Ublock Origin chặn tập lệnh.) Nhưng, đây là thứ tôi cần.
ale

Tôi sợ nó bị lỗi thời, giờ đây :( Lỗi Loại: Không thể đọc thuộc 'bao gồm' của undefined tại getVisibleTracks (<anonymous>: 20: 43) tại <anonymous>: 49: 5 tại c ( play-music.gstatic.com/ phong / 6..e / lắng__en_gb.js: 1190: 211 )
FloriOn

4
@FloriOn Cảm ơn bạn đã bình luận! Tôi đã cập nhật mã để nó hoạt động trở lại.
Zach Saucier

2
@ale Có. Bạn có thể biến mã thành bookmarklet.
David Metcalfe

Lỗi bảng điều khiển xuất hiện khi chạy mã này, nhưng dường như nó không chặn được mã chạy
Otheus

31

(Cập nhật 2016-05-09, mạnh mẽ hơn câu trả lời hàng đầu hiện tại)

Nếu bạn chỉ cần lưu một vài danh sách phát, bạn có thể sử dụng đoạn mã Javascript của tôi bên dưới. Đoạn mã này có thể lưu mọi danh sách khi nó được hiển thị trên trang web, do đó, nó cũng hoạt động cho tất cả các lượt xem thư viện bài hát / album / nghệ sĩ. Tôi đã liệt kê hai lựa chọn thay thế khác ở cuối câu trả lời này.

  1. Truy cập: https://play.google.com/music/listen#/all (hoặc danh sách phát của bạn)

  2. Mở bảng điều khiển dành cho nhà phát triển (F12 cho Chrome). Dán mã dưới đây vào bàn điều khiển.

  3. Tất cả các bài hát bị loại bỏ được lưu trữ trong allsongsđối tượng và một phiên bản văn bản của danh sách được sao chép vào bảng tạm. Tôi khuyên bạn nên chạy songsToText("all",true)sau đó để có được thông tin CSV đầy đủ. Chạy copy(outText)thủ công nếu sao chép clipboard không hoạt động trong lần thử đầu tiên.

Mã (phiên bản mới nhất ngày 10 tháng 5 năm 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);

Mã mới nhất trên Github (Gist) tại đây: https://gist.github.com/jmiserez/c9a9a0f41e867e5ebb75

  • Nếu bạn muốn đầu ra ở định dạng văn bản, có thể gọi hàm testsToText (). Bạn có thể chọn một kiểu, chọn định dạng và nếu chỉ xuất các bài hát thích / bật ngón tay cái lên. Danh sách kết quả sau đó sẽ được dán vào bảng tạm. Styles là all, artist, artistalbum, artistsong, artistalbumsong. CSV sẽ dẫn đến một tệp CSV và có thể bị bỏ qua (mặc định là sai). Likedonly có thể bị bỏ qua (mặc định là false) hoặc được đặt thành true và sẽ lọc tất cả các bài hát có xếp hạng lớn hơn hoặc bằng 5. Ví dụ:

    • songsToText("all",true,false) sẽ xuất tất cả các bài hát ở định dạng csv.
    • songsToText("all",true,true) sẽ chỉ xuất các bài hát thích ở định dạng csv.
    • songsToText("artistsong",false,false) sẽ xuất tất cả các bài hát dưới dạng văn bản.
  • Sau đó, bạn có thể dán dữ liệu vào bất cứ nơi nào bạn thích, ví dụ: http://www.ivyishere.org/ nếu bạn muốn thêm các bài hát hoặc album vào tài khoản Spotify của mình. Để làm cho Ivy nhận ra album đầy đủ, hãy sử dụng phong cách "artistalbum". Đối với các bài hát, sử dụng phong cách "artistong".

Về đoạn trích: Điều này dựa trên câu trả lời ban đầu của Michael Smith, nhưng mạnh mẽ hơn một chút. Tôi đã thực hiện các cải tiến sau:

  • Hoạt động trên danh sách phát cũng như thư viện. Bất kỳ cột bị thiếu nào đều bị bỏ qua và thứ tự được tìm ra, do đó, nó sẽ hoạt động trên hầu hết mọi danh sách bài hát trong Google Music.

  • Nó dừng hoặc khi chạm đến đáy (phát hiện vị trí cuộn) hoặc sau khi hết thời gian đã chỉ định. Thời gian chờ là có để ngăn chặn một vòng lặp vô tận trong trường hợp mã phát hiện cuộn bị tắt bởi một vài pixel.

  • Nó nhanh hơn nhiều (khoảng cách mỗi 1ms), nhưng chờ đợi nếu dữ liệu chưa sẵn sàng (tối đa là thời gian chờ đã chỉ định, hiện tại là 3 giây).

  • Không trùng lặp trong quá trình hoạt động và trên đầu ra.

  • Xếp hạng tập hợp: "không xác định" không bao giờ được xếp hạng, "0" không được xếp hạng (nghĩa là một khi được xếp hạng nhưng sau đó bị xóa), "1" là ngón tay cái xuống và "5" là ngón tay cái lên (thích).

Ngoài những cải tiến cơ bản, nó cũng định dạng văn bản độc đáo và sao chép nó vào bảng tạm. Bạn cũng có thể lấy dữ liệu dưới dạng CSV nếu muốn, bằng cách chạy songsToTextchức năng lần thứ hai.

Lựa chọn thay thế:

  1. Nếu bạn cần API Python, hãy xem dự án Google Music API không chính thức .

  2. Nếu bạn có hàng tấn danh sách phát và muốn xuất tất cả chúng trong một lần, hãy thử trình xuất danh sách phát gmusic-scripts có thể làm điều đó (Python, sử dụng dự án API không chính thức).


Đây chỉ là phần tiếp theo của mã: nó chỉ dẫn đến 30 bài hát cuối cùng được sao chép và khi tôi thực hiện các bài hát ToText ("artistong"), nó sẽ tạo ra độ dài tính bằng phút: giây và số lượng bản nhạc trong danh sách phát. dù sao thì các chi tiết bài hát cũng có trong allsong, nhưng chỉ có 30 trong số đó (tôi có danh sách phát với hàng trăm)
mkln

Không quan tâm đến số lượng bài hát, nó không bị kẹt ở 30. Nhưng trên một danh sách phát khác với 130 bài hát, nó chỉ xuất 117
mkln

@mkln Tôi đã cập nhật mã, bây giờ nó xử lý thư viện, danh sách phát cũng như mọi danh sách bài hát khác trong Google Music. Chỉ cần chạy mọi thứ và nó sẽ sao chép danh sách phát / thư viện / danh sách dưới dạng danh sách văn bản vào bảng tạm. Nếu bạn cần phiên bản CSV bao gồm mọi thứ (số lần phát, thời lượng, xếp hạng), hãy chạy songsToText("all", true)sau đó.
jmiserez

nó hoạt động rất tốt, cảm ơn Tôi đang cố gắng viết một kịch bản python lưu tất cả danh sách phát. Làm thế nào bạn có thể nhấp vào danh sách phát khác nhau thông qua javascript? có thể có một bộ chọn danh sách phát ở đầu chức năng không?
mkln

1
@mkln Chà, anh chàng này đã làm được điều đó: github.com/soulfx/gmusic-playlist Có lẽ dễ nhất nếu bạn chỉ sử dụng tập lệnh Python của anh ấy! Tôi thực sự không thấy điều này cho đến bây giờ, nhưng có lẽ đó là lựa chọn tốt hơn nếu bạn cần nhiều hơn một danh sách phát.
jmiserez

18

Nếu bạn không ngại chạy một chút mã javascript trong bảng điều khiển dành cho nhà phát triển trình duyệt, bạn có thể trích xuất thông tin từ trang như vậy (chỉ được thử nghiệm trong Chrome):

var playlist = document.querySelectorAll('.song-table tr.song-row');
for(var i =0; i<playlist.length ; i++) { 
  var l = playlist[i]; 
  var title = l.querySelector('td[data-col="title"] .column-content').textContent;
  var artist = l.querySelector('td[data-col="artist"] .column-content').textContent;
  var album = l.querySelector('td[data-col="album"] .column-content').textContent;
  console.log(artist + ' --- ' + title + ' --- ' + album); 
}

Điều này sẽ in ra bảng điều khiển một danh sách hầu hết các bài hát hiện có thể nhìn thấy trong cửa sổ. Bạn sẽ cần phải cuộn xuống và chạy lại để có thêm. Hiện tại tôi chưa tìm ra cách nào để nắm bắt toàn bộ thông tin, nhưng bản hack 5 phút nhanh này vẫn tốt hơn là không có gì.


Điều này có vẻ đầy hứa hẹn. Tôi sẽ cho nó đi.
ale

2
Cảm ơn bạn rất nhiều vì câu trả lời này. Bạn đã tiết kiệm cho tôi hàng giờ và thời gian. Những gì tôi đã làm là chạy tập lệnh của bạn nhiều lần trong danh sách nhạc tôi muốn sao chép. Dán kết quả vào ứng dụng Mac có tên là Text Soap. Đã trở thành ",". Loại bỏ trùng lặp và xuất ra dưới dạng txt. Sau đó, thay đổi nó để CSV, tước ra các cột unneded và nhập khẩu nó vào Spotify sử dụng: ivyishere.org Tất cả trong tất cả đã cho tôi khoảng 8 phút một tôi đã được hang của nó, cheers ~

Không có vấn đề, rất vui khi được giúp đỡ.
darkl Liquid

Điều này có vẻ như nó sẽ thực hiện các mẹo. Vấn đề lớn nhất của tôi là kích thước danh sách phát của tôi - 180 trên danh sách tôi đang cố gắng xuất. Tôi đã khắc phục điều đó một chút bằng cách tối đa hóa cửa sổ Chrome của mình và sau đó thu nhỏ hết mức có thể. Nếu tôi có thể thuyết phục Chrome phóng to lên 10% thì tôi có tất cả trên một màn hình ... ở mức 25%, phải mất hai vòng cộng thêm một chút nữa. (Bất kỳ cơ hội nào bạn có thể phóng to từ JS?)
RobertB 19/12/13

1
FYI, nếu bạn chỉ là một yếu tố, hãy sử dụng querySelector(...)thay vìquerySelectorAll(...)[0]
ThiefMaster

3

Sử dụng câu trả lời hàng đầu (vào thời điểm đó) và muốn có một giải pháp hoàn chỉnh, tôi đã tạo mã sau đây để cuộn xuống danh sách nhạc và thêm các đối tượng JSON vào một mảng khi nó đi.

Do không biết chính xác những bài hát có thể nhìn thấy, mã thêm tất cả chúng, sau đó sao chép lại ở cuối. (Chỉ được thử nghiệm trong Chrome.)

Để sử dụng: đi đến thư viện của bạn, nơi bạn thấy danh sách bài hát đầy đủ của mình và chạy

var total = [];
var interval = setInterval(function(){
    var songs = document.querySelectorAll("table.song-table tbody tr.song-row");
    for (var i = 0; i < songs.length; i++) {
        total.push({name: songs[i].childNodes[0].textContent,
        length: songs[i].childNodes[1].textContent,
        artist: songs[i].childNodes[2].textContent,
        album: songs[i].childNodes[3].textContent,
        plays: songs[i].childNodes[4].textContent
        });
        songs[i].scrollIntoView(true);
    }
}, 800);

Khi điều đó đến cuối trang, hãy chạy nó để dừng mảng cuộn, khử trùng lặp và sao chép JSON vào clipboard.

clearInterval(interval);
for (var i = 0; i < total.length; i++) {
    for (var j = i + 1; j < total.length; j++) {
        if (total.hasOwnProperty(i) && total.hasOwnProperty(j) && total[i].name == total[j].name && total[j].artist == total[i].artist) {
            total.splice(j,1);
        }
    }
}
copy(total);

3

Tôi có một số JavaScript ngắn hơn nhiều mà bạn có thể dán vào bảng điều khiển. Thay vì chạy lại mã, bạn có thể chỉ cần cuộn xuống và tất cả các album xuất hiện được xem. Sau đó, bạn có thể tải xuống danh sách phát dưới dạng bảng tính.

Hướng dẫn

  1. Truy cập tại đây: https://play.google.com/music/listen#/ap/auto-playlist-thumbs-up

  2. Mở Công cụ dành cho nhà phát triển (F12) và dán mã bên dưới vào tab Bảng điều khiển

  3. Cuộn xung quanh để mỗi album trong danh sách phát được hiển thị ít nhất một lần

  4. Nhấp đúp vào nơi nào đó trên trang để tải xuống export-google-play.csv

  5. Mở export-google-play.csvtrong Excel.

alert("Please scroll through the playlist so that each album is visible once.\n" + 
      "Then double-click the page to export a spreadsheet.");
var albums = ["Artist,Album,Purchased"];

var addVisibleAlbums = function(){
    [].forEach.call(document.querySelectorAll(".song-row"), function(e){ 
        var albumNodes = [e.querySelector("td[data-col='artist']"), 
              e.querySelector("td[data-col='album']"),
              e.querySelector("td[data-col='title'] .title-right-items")];

        var albumString = albumNodes.map(function(s){ 
            return s.innerText.trim().replace(/,/g,""); 
        }).join(",");

        if(albums.indexOf(albumString) === -1){
            albums.push(albumString); console.log("Added: " + albumString)
        }
    });
}

var createCsv = function(){
    var csv = "data:text/csv;charset=utf-8,";
    albums.forEach(function(row){ csv += row + "\n"; }); 

    var uri = encodeURI(csv);
    var link = document.createElement("a");
    link.setAttribute("href", uri);
    link.setAttribute("download", "export-google-play.csv");
    document.body.appendChild(link);
    link.click(); 
    alert("Download beginning!")
}

document.body.addEventListener("DOMNodeInserted", addVisibleAlbums, false);
document.body.addEventListener("dblclick", createCsv, false);

Đầu ra

nhập mô tả hình ảnh ở đây

GitHub


2

Tôi đã sửa đổi cách tiếp cận của câu trả lời hàng đầu một chút. Điều này làm việc tốt hơn với tôi với phương pháp sao chép / dán của Ivy ( http://www.ivyishere.org/ivy ):

Bước 1 Mở danh sách phát bạn muốn từ Google Music trong Chrome và dán danh sách này vào bảng điều khiển:

document.querySelector('body.material').style.height = (document.querySelector('table.song-table tbody').getAttribute('data-count') * 100) + 'px';

Điều này sẽ khiến toàn bộ danh sách phát của bạn hiển thị thay vì chỉ một phần.

Bước 2 Dán đoạn script này vào bàn điều khiển:

var i, j, playlistString = '', playlist = document.querySelectorAll('.song-table tr.song-row');
for (i = 0, j = playlist.length; i < j; i++) {
    var track = playlist[i]; 
    var artist = track.querySelector('[href][aria-label]').textContent;
    var title = track.querySelector('td[data-col="title"]').textContent;
    playlistString += ('"' + artist + '", "' + title + '"\n');
}
console.log(playlistString);

Bước 3 Chuyển đến Ivy và khi bạn đến bước 2 ở đó, hãy chọn tab Copy / Paste và dán đầu ra giao diện điều khiển vào đó.

BIÊN TẬP

Kịch bản cập nhật được đề xuất bởi Alex Pedersen

Lặp đi lặp lại về sàng lọc samurauturetskys (Tôi chưa đủ danh tiếng để nhận xét về bài đăng của mình). Tôi nghĩ rằng kiểu dáng Googleplay đã được cập nhật nên kịch bản bên dưới một lần nữa cho kết quả khá.

var i, j, playlistString = '', playlist = document.querySelectorAll('.song-table tr.song-row');
for (i = 0, j = playlist.length; i < j; i++) {
    var track = playlist[i]; 
    var artist = track.querySelector('[href][aria-label]').textContent;
    var title = track.querySelector('span[class="column-content fade-out tooltip"]').textContent;
    playlistString += ('"' + artist + '", "' + title + '"\n');
}
console.log(playlistString);

-1

Đơn giản chỉ cần làm Ctrl+ cho đến khi văn bản rất nhỏ và sau đó chọn tất cả. Nó hoạt động như một sự quyến rũ mà không có kịch bản và ứng dụng.


-2

Tôi chỉ đi qua câu hỏi này để tìm kiếm một cái gì đó tương tự.

Tôi đoán, lựa chọn tốt nhất của bạn là:

  1. cài đặt một ứng dụng như "Sao lưu danh sách phát"
  2. Xuất danh sách phát nhạc của Google sang tệp văn bản với ứng dụng này.
  3. Đổi tên thành .m3u bằng ứng dụng Trình quản lý tệp (như Ghost Commander)
  4. Mở danh sách phát với một ứng dụng khác có nhiều tùy chọn hơn (như MusiXMatch).

1
Tôi giả sử bạn có nghĩa là ứng dụng này . Không tốt. Trong khi tôi có một thiết bị Android, tôi không tìm kiếm một giải pháp Android. Hơn nữa, tôi đã dùng thử ứng dụng này và nó không thể xuất dữ liệu trên các bản nhạc không có trên thiết bị, vì vậy nó vô dụng với tôi.
ale

1
Oliver, là Ứng dụng web, chúng tôi thích các câu trả lời không yêu cầu ứng dụng gốc.
Vidar S. Ramdal
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.