Google Play 뮤직에서 재생 목록 인쇄


43

Google Play 뮤직 계정 에서 노래 목록 (아티스트, 앨범, 등급 및 가능한 경우 재생 횟수 및 재생 시간 포함)을 인쇄하고 싶습니다 .

앱에서이를 수행하는 쉬운 방법은 없습니다. 긴 노래 목록을 통해 페이지를 인쇄 할 때 인쇄 화면을 만드는 것은 불가능합니다.

본인이 조작 할 수있는 표준 형식 (일반 텍스트, CSV, XML 등)으로 데이터를 내보내는 것에 만족합니다.

어떤 제안?


답변:


17

darkliquid의 답변을 수정 하여 여러 재생 목록을 한 번에 저장할 수있는 다음을 생각해 냈습니다 .

명령:

  1. 재생 목록 페이지로 이동 하십시오 .
  2. 아래 자바 스크립트 코드를 콘솔에 붙여 넣습니다.
  3. 텍스트로 저장하려는 재생 목록을 클릭하십시오.
  4. 재생 목록 페이지에서 하단으로 비교적 천천히 스크롤하십시오.
  5. 하단으로 스크롤 한 후 메뉴 또는 브라우저의 뒤로 버튼을 사용하여 재생 목록 페이지 (1 단계와 동일)로 돌아갑니다.
  6. 텍스트에 저장하려는 모든 재생 목록에 대해 3-5 단계를 반복하십시오.
  7. 당신이 모든 텍스트에 저장할 재생 목록을이 과정을 마친 후에는 중 하나를 입력 할 수 있습니다 JSON.stringify(tracklistObj, null, '\t')합니다 (변경 '\t'' '당신이 최소한의 들여 쓰기를 원하는 경우) 또는 tracklistObj그냥 원하는 경우 자바 스크립트 객체는 그것을 자신의 방식으로 조작 할 수 있습니다. 정렬하려면 명령 Object.values(tracklistObj).forEach(a => a.sort()) 호출 하기 전에 명령을 실행하십시오 JSON.stringify.

수행하려는 모든 작업을 완료하기 전에 페이지를 새로 고치지 않도록주의하십시오. 그렇지 않으면 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;

당신이 변경 가서 당신은 또한 콘솔에 트랙 이름을 인쇄 할 수 있습니다 printTracksToConsoletrue(3 단계 전에이 작업을 수행해야합니다).

콘솔에서 모든 GET 및 POST 오류를 무시할 수 있습니다 (이 스크립트는 Play 뮤직 자체에서 생성됨).

또한 현재 그것의 설정 만 제공하는 점에 유의 Artist - Track name,하지만 당신은 쉽게 가지고 라인 편집 할 수 있습니다 tracklistObj[currentPlaylist].push(artist + " - " + title);로를 album, playCount, duration, 또는 rating, 및 / 또는 당신이 무엇을 (만약 당신이 너무 CSV 형식을하시기 바랍니다 포함) 원하는 포맷.

기본 설정의 예제 출력 (현재 보유한 모든 Google Play 재생 목록) 32 개의 재생 목록 각각을 탐색하고 아래로 스크롤 한 다음 결과를 텍스트로 변환하는 데 총 5 분이 걸렸습니다.

추신 : 내 음악 조정 이라는 사이트를 사용 하여 친구들이 Google Playlists를들을 수 있도록 출력에서 ​​YouTube 재생 목록을 만들 수 있지만 (YouTube는 재생 목록 생성을 하루 10으로 제한) 관심이있을 수 있습니다 . 이 작업을 수행하는 경우 TextMechanic 과 같은 것을 사용 하여 따옴표를 제거 .mp3하고 출력 목록에서 제거 할 수 있습니다.


1
콘솔에 JavaScript를 붙여 넣는 것보다 더 좋은 방법이 있다면. (Ublock Origin이 스크립트를 차단 한 이후에도 약간의 딸꾹질이있었습니다.) 그러나 이것이 필요한 작업입니다.
ale

<익명>에서 부동산 (43 : 20 <익명>) : getVisibleTracks에서 정의되지 않은의 '포함'을 읽을 수 없습니다 : 나는 지금 :( 형식 오류를 오래된됩니다 두려워 49 : C에서 5 ( play-music.gstatic.com/ fe / 6..e / listen__en_gb.js : 1190 : 211 )
FloriOn

4
@FloriOn 의견을 보내 주셔서 감사합니다! 코드가 업데이트되어 다시 작동합니다.
Zach Saucier

2
@ale 있습니다. 코드를 북마크릿으로 바꿀 수 있습니다.
David Metcalfe

이 코드를 실행할 때 콘솔 오류가 나타나지만 실행을 차단하지 않는 것 같습니다
Otheus

31

(2016-05-09로 업데이트되어 현재 최고 답변보다 강력 함)

재생 목록을 몇 개만 저장하면 아래의 자바 스크립트 스 니펫을 사용할 수 있습니다. 이 스 니펫은 웹 페이지에 표시된대로 모든 목록을 저장할 수 있으므로 모든 노래 / 앨범 / 아티스트 라이브러리보기에서도 작동합니다. 이 답변의 끝에 다른 두 가지 대안을 나열했습니다.

  1. 로 이동 https://play.google.com/music/listen#/all (또는 재생 목록)

  2. 개발자 콘솔 (F12 for Chrome)을 엽니 다. 아래 코드를 콘솔에 붙여 넣습니다.

  3. 스크랩 된 모든 노래가 allsongs개체에 저장되고 목록의 텍스트 버전이 클립 보드에 복사됩니다. songsToText("all",true)전체 CSV 정보를 얻으려면 나중에 실행하는 것이 좋습니다 . copy(outText)첫 번째 시도에서 클립 보드 복사가 작동하지 않으면 수동으로 실행하십시오 .

코드 (최신 버전 2016 년 5 월 10 일, 개정판 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);

Github (Gist)의 최신 코드는 다음과 같습니다. https://gist.github.com/jmiserez/c9a9a0f41e867e5ebb75

  • 텍스트 형식의 출력을 원하면 songsToText () 함수를 호출 할 수 있습니다. 스타일을 선택하고, 형식을 선택할 수 있으며, 좋아하거나 축소 된 노래 만 내 보내야합니다. 결과 목록이 클립 보드에 붙여 넣어집니다. 스타일은 all, artist, artistalbum, artistsong, artistalbumsong. CSV는 CSV 파일을 생성하며 생략 될 수 있습니다 (기본값은 false). 마찬가지로 생략하거나 (기본값은 false) true로 설정할 수 있으며 등급이 5 이상인 모든 노래를 필터링합니다. 예 :

    • songsToText("all",true,false) 모든 노래를 CSV 형식으로 내 보냅니다.
    • songsToText("all",true,true) 좋아하는 노래 만 CSV 형식으로 내 보냅니다.
    • songsToText("artistsong",false,false) 모든 노래를 텍스트로 내 보냅니다.
  • 노래 나 앨범을 Spotify 계정에 추가하려는 경우 http://www.ivyishere.org/ 와 같이 원하는 위치에 데이터를 붙여 넣을 수 있습니다 . 아이비가 풀 앨범을 인식하게하려면 "artistalbum"스타일을 사용하십시오. 노래의 경우 "artistsong"스타일을 사용하십시오.

스 니펫 정보 : 이것은 Michael Smith의 원래 답변을 기반으로하지만 조금 더 강력합니다. 나는 다음과 같이 개선했다 :

  • 라이브러리뿐만 아니라 재생 목록에서도 작동합니다. 누락 된 열은 무시되고 순서가 파악되므로 Google 뮤직의 거의 모든 노래 목록에서 작동합니다.

  • 하단에 도달하거나 (스크롤 위치 감지) 또는 지정된 시간 초과 후 중지됩니다. 스크롤 감지 코드가 몇 픽셀만큼 꺼져있는 경우 무한 루프를 방지하기 위해 타임 아웃이 있습니다.

  • 훨씬 빠르지 만 (1ms 간격) 데이터가 준비되지 않은 경우 (현재 지정된 시간 초과 (현재 3 초)까지) 대기합니다.

  • 작동 중 및 출력시 중복 제거를 수행합니다.

  • 등급 수집 : "정의되지 않음"은 평가되지 않으며, "0"은 평가되지 않습니다 (즉, 일단 평가되었지만 제거 된 경우), "1"은 거절되고 "5"는 거절됩니다 (좋아요).

기본 개선 사항 외에도 텍스트를 멋지게 형식화하고 클립 보드에 복사합니다. songsToText함수를 두 번 실행하여 원하는 경우 데이터를 CSV로 가져올 수도 있습니다 .

대안 :

  1. Python API가 필요한 경우 비공식 Google Music API 프로젝트를 확인하십시오 .

  2. 많은 재생 목록이 있고 한 번에 모든 재생 목록을 내보내려면 gmusic-scripts 재생 목록 내보내기를 시도하십시오 (Python, 비공식 API 프로젝트 사용).


코드에 대한 후속 조치 만하면 마지막 30 곡만 복사되고 songsToText ( "artistsong") 할 때 길이를 분 : 초 단위로 표시하고 재생 목록의 트랙 번호를 출력합니다. 노래 세부 사항은 어쨌든 allsongs에 있지만, 그 중 30 개만 있습니다 (수백 개의 재생 목록이 있음)
mkln

노래 수에 대해서는 신경 쓰지 않고 30에 고정되지 않습니다. 그러나 130 곡의 다른 재생 목록에서는 처음 117 만 내 보냅니다.
mkln

@mkln 코드를 업데이트했습니다. 이제 라이브러리, 재생 목록 및 Google 뮤직의 다른 모든 노래 목록을 처리합니다. 모든 것을 실행하면 재생 목록 / 라이브러리 / 목록이 텍스트 목록으로 클립 보드에 복사됩니다. 모든 것을 포함하는 CSV 버전이 필요한 경우 (재생 횟수, 기간, 등급) songsToText("all", true)나중에 실행하십시오 .
jmiserez

감사합니다. 모든 재생 목록을 저장하는 파이썬 스크립트를 작성하려고합니다. 자바 스크립트를 통해 다양한 재생 목록을 어떻게 클릭 하시겠습니까? 기능의 시작 부분에 재생 목록 선택기를 가질 수 있습니까?
mkln

1
@mkln 글쎄요.이 사람은 이미 그 일을했습니다 : github.com/soulfx/gmusic-playlist 파이썬 스크립트를 사용하면 가장 쉬울 것입니다! 솔직히 지금까지 이것을 보지 못했지만 둘 이상의 재생 목록이 필요한 경우 더 나은 옵션 일 것입니다.
jmiserez 1

18

브라우저 개발자 콘솔에서 약간의 자바 스크립트 코드를 실행하지 않아도되는 경우 페이지에서 정보를 추출 할 수 있습니다 (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); 
}

창에 현재 보이는 대부분의 노래 목록이 콘솔에 출력됩니다. 더 많이 얻으려면 아래로 스크롤 한 후 다시 실행해야합니다. 지금은 정보를 완전히 파악하는 적절한 방법을 찾지 못했지만이 5 분의 빠른 해킹은 아무것도 아닌 것보다 낫습니다.


이것은 유망 해 보인다. 나는 그것을 줄 것이다.
ale

2
이 답변에 감사드립니다. 시간과 시간을 절약했습니다. 내가 한 것은 복사하려는 재생 목록에서 스크립트를 반복해서 실행하는 것입니다. 결과를 Text Soap이라는 Mac 앱에 붙여 넣습니다. 으로 변하다 ",". 중복을 제거하고 txt로 내보냈습니다. 그런 다음 사용하여 스포티 파이로, CSV로 변경 한 unneded 열을 제거하고 수입 : ivyishere.org 모두 모두 팔분 하나 나는 그것의 취급있어, 환호 ~에 대해 날 데려 갔어

문제 없습니다. 기꺼이 도와 드리겠습니다.
darkliquid

트릭을 수행하는 것처럼 보입니다. 내 가장 큰 문제는 내 재생 목록의 크기입니다-내보내려는 파일의 크기는 180입니다. Chrome 창을 최대화 한 다음 가능한 한 축소하여 문제를 해결했습니다. Chrome에서 10 %로 확대하도록 설득 할 수 있다면 한 화면에 25 %로 표시하면 두 번의 라운드에 약간 더 걸립니다. (언제든지 JS에서 확대 할 수 있습니까?)
RobertB

1
참고로, 하나의 요소 만 사용 querySelector(...)하는 경우 대신 대신 사용하십시오querySelectorAll(...)[0]
ThiefMaster

3

상단 답변 (당시)을 사용하고 완벽한 솔루션을 원하면서 음악 목록을 아래로 스크롤하여 JSON 객체를 배열에 추가하는 다음 코드를 만들었습니다.

어떤 노래가 보이는지 정확히 알지 못하기 때문에 코드는 모든 노래를 추가 한 다음 끝에 중복 제거됩니다. (Chrome에서만 테스트되었습니다.)

사용하려면 : 전체 노래 목록을 볼 수있는 라이브러리로 이동하여

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);

그것이 페이지의 맨 아래에 도착하면 이것을 스크롤하여 중복 제거하고 배열을 삭제하고 JSON을 클립 보드에 복사하십시오.

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

콘솔에 붙여 넣을 수있는 훨씬 짧은 JavaScript가 있습니다. 코드를 다시 실행하는 대신 아래로 스크롤하면 보이는 모든 앨범이 추가됩니다. 그런 다음 재생 목록을 스프레드 시트로 다운로드 할 수 있습니다.

명령

  1. 여기로 이동 : https://play.google.com/music/listen#/ap/auto-playlist-thumbs-up

  2. 개발자 도구 (F12)를 열고 아래 코드를 콘솔 탭에 붙여 넣습니다.

  3. 재생 목록의 각 앨범이 한 번 이상 표시되도록 스크롤합니다.

  4. 다운로드 할 페이지의 어딘가를 두 번 클릭하십시오 export-google-play.csv

  5. export-google-play.csvExcel에서 엽니 다 .

암호

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);

산출

여기에 이미지 설명을 입력하십시오

깃 허브


2

나는 최고 답변의 접근 방식을 약간 수정했습니다. 이것은 아이비의 복사 / 붙여 넣기 방법 ( http://www.ivyishere.org/ivy )으로 나에게 더 효과적이었습니다 .

1 단계 Chrome의 Google 뮤직에서 원하는 재생 목록을 열고 콘솔에 붙여 넣습니다.

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

이로 인해 전체 재생 목록이 일부가 아닌 렌더링됩니다.

2 단계이 스크립트를 콘솔에 붙여 넣습니다.

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);

3 단계 아이비로 이동하여 2 단계로 이동 하면 복사 / 붙여 넣기 탭을 선택하고 콘솔 출력을 붙여 넣습니다.

편집하다

Alex Pedersen이 제안한 업데이트 된 스크립트

samurauturetskys 세련미를 반복합니다 (아직 그의 게시물에 대해 언급 할만 큼 명성이 없습니다). Googleplay 스타일이 업데이트되어 아래 스크립트가 다시 출력됩니다.

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

간단하게 할 Ctrl+를 텍스트가 매우 작다까지 후 모두 선택합니다. 스크립트와 앱이없는 매력처럼 작동합니다.


-2

방금이 질문을 통해 비슷한 것을 찾았습니다.

최선의 선택은 다음과 같습니다.

  1. "플레이리스트 백업"과 같은 앱 설치
  2. 이 앱으로 Google 뮤직 재생 목록을 텍스트 파일로 내 보냅니다.
  3. FileManager 앱 (예 : Ghost Commander)을 사용하여 .m3u로 이름을 바꿉니다.
  4. 더 많은 옵션이있는 다른 앱 (예 : MusiXMatch)으로 재생 목록을 엽니 다.

1
나는 당신 이이 응용 프로그램 을 의미한다고 가정합니다 . 좋지 않다. Android 기기를 사용하는 동안 Android 솔루션을 찾지 않습니다. 또한이 앱을 사용해 보았는데 장치에없는 트랙의 데이터를 내보낼 수 없으므로 나에게 쓸모가 없습니다.
ale

1
Oliver는 웹 응용 프로그램이므로 기본 응용 프로그램이 필요없는 답변을 선호합니다.
Vidar S. Ramdal
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.