Wydrukuj listę odtwarzania z Muzyki Google Play


43

Chcę wydrukować listę utworów (z wykonawcą, albumem, oceną oraz, jeśli to możliwe, liczbą odtworzeń i czasem trwania) z mojego konta Muzyki Google Play .

Nie ma łatwego sposobu na zrobienie tego z poziomu aplikacji. Robienie ekranów podczas przeglądania długiej listy utworów jest nie do zniesienia.

Byłbym zadowolony z eksportu danych do standardowego formatu (zwykły tekst, CSV, XML itp.), Którym sam mogę manipulować.

Jakieś sugestie?


Odpowiedzi:


17

Modyfikując odpowiedź darkliquid za , ja przyszedłem z następujących składników, które pozwala na wielokrotne listy mają być zapisane na raz .

Instrukcje:

  1. Przejdź do strony listy odtwarzania .
  2. Wklej poniższy kod JavaScript do swojej konsoli.
  3. Kliknij listę odtwarzania, którą chcesz zapisać w tekście.
  4. Na stronie listy odtwarzania przewiń stosunkowo powoli do dołu.
  5. Po przewinięciu w dół przejdź z powrotem do strony list odtwarzania (tak jak w kroku 1.) za pomocą przycisku menu lub przeglądarki wstecz.
  6. Powtórz kroki 3-5 dla wszystkich list odtwarzania, które chcesz zapisać w tekście.
  7. Kiedy już to zrobisz to dla wszystkich list odtwarzania, które chcesz zapisać na tekście, można wpisać JSON.stringify(tracklistObj, null, '\t')(zmienić '\t'się ' ', jeśli chcesz minimalne wcięcie) lub tracklistObjjeśli chcesz po prostu obiektem JavaScript, żeby manipulować swoją własną drogę. Jeśli chcesz to posortować, uruchom polecenie Object.values(tracklistObj).forEach(a => a.sort()) przed wywołaniem JSON.stringifypolecenia.

Uważaj, aby nie odświeżyć strony przed ukończeniem wszystkiego, co chcesz zrobić, w przeciwnym razie będziesz musiał ponownie uruchomić od kroku 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;

Możesz także wydrukować nazwy ścieżek na konsoli, przechodząc printTracksToConsoledo true(powinieneś to zrobić przed krokiem 3).

Pamiętaj, że prawdopodobnie możesz zignorować wszystkie błędy GET i POST w konsoli (są one generowane przez samą Muzykę Play, a nie przez ten skrypt).

Należy również pamiętać, że obecnie jest to konfiguracja tylko dać Artist - Track name, ale łatwo można edytować linię, która ma tracklistObj[currentPlaylist].push(artist + " - " + title);z album, playCount, duration, lub ratingi / lub cokolwiek formatowanie chcesz (w tym formacie CSV, jeśli tak proszę).

Przykładowe dane wyjściowe (wszystkie listy odtwarzania Google Play, które obecnie posiadam) z ustawieniami domyślnymi. Przejście do każdej z 32 list odtwarzania, przewinięcie w dół, a następnie przekonwertowanie wyniku na tekst zajęło w sumie około 5 minut.

PS Możesz zainteresować się witryną o nazwie Tune My Music, aby tworzyć listy odtwarzania YouTube (ale YouTube ogranicza tworzenie list odtwarzania do 10 dziennie) z wyników, aby Twoi znajomi mogli słuchać Twoich list odtwarzania Google. Jeśli to zrobisz, prawdopodobnie chcesz użyć czegoś takiego jak TextMechanic, aby usunąć cudzysłowy i .mp3z listy wyników.


1
Gdyby tylko był na to lepszy sposób niż wklejenie JavaScript w konsoli. (Miałem też małą czkawkę, odkąd Ublock Origin zablokował skrypt.) Ale to robi to, czego potrzebuję.
ale

Obawiam się, że jest teraz nieaktualny :( TypeError: Cannot read property 'include' of undefined w getVisibleTracks (<anonymous>: 20: 43) w <anonymous>: 49: 5 at c ( play-music.gstatic.com/ fe / 6..e / listen__en_gb.js: 1190: 211 )
FloriOn

4
@FloriOn Dziękujemy za komentowanie! Zaktualizowałem kod, aby znów działał.
Zach Saucier

2
@ale Jest. Możesz zmienić kod w bookmarklet.
David Metcalfe

Podczas uruchamiania tego kodu pojawiają się błędy konsoli, ale nie wydaje się, aby blokowało to działanie
Otheus

31

(Zaktualizowano 2016-05-09, bardziej solidny niż aktualna najlepsza odpowiedź)

Jeśli chcesz tylko zapisać kilka list odtwarzania, możesz po prostu użyć poniższego fragmentu kodu JavaScript. Ten fragment kodu może zapisać każdą listę, tak jak jest pokazana na stronie internetowej, więc działa również dla wszystkich widoków bibliotek utworów / albumów / artystów. Na końcu tej odpowiedzi wymieniłem dwie inne alternatywy.

  1. Wejdź na: https://play.google.com/music/listen#/all (lub swoją listę odtwarzania)

  2. Otwórz konsolę programisty (F12 dla Chrome). Wklej kod poniżej do konsoli.

  3. Wszystkie zeskrobane utwory są przechowywane w allsongsobiekcie, a tekstowa wersja listy jest kopiowana do schowka. Polecam uruchomić songsToText("all",true)później, aby uzyskać pełne informacje o CSV. Uruchom copy(outText)ręcznie, jeśli kopiowanie ze schowka nie działało przy pierwszej próbie.

Kod (najnowsza wersja 10 maja 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);

Najnowszy kod na Github (Gist) tutaj: https://gist.github.com/jmiserez/c9a9a0f41e867e5ebb75

  • Jeśli chcesz otrzymać wynik w formacie tekstowym, możesz wywołać funkcję songsToText (). Możesz wybrać styl, wybrać format, a jeśli tylko polubione / polecone utwory powinny zostać wyeksportowane. Wynikowa lista zostanie następnie wklejona do schowka. Style all, artist, artistalbum, artistsong, artistalbumsong. Plik CSV spowoduje utworzenie pliku CSV i można go pominąć (domyślnie false). Likedonly może zostać pominięty (domyślnie false) lub ustawiony na true, i będzie filtrował wszystkie utwory z ocenami większymi lub równymi 5. Np .:

    • songsToText("all",true,false) wyeksportuje wszystkie utwory w formacie csv.
    • songsToText("all",true,true) wyeksportuje tylko lubiane utwory w formacie csv.
    • songsToText("artistsong",false,false) wyeksportuje wszystkie utwory jako tekst.
  • Następnie możesz wkleić dane w dowolnym miejscu, na przykład http://www.ivyishere.org/, jeśli chcesz dodać utwory lub albumy do konta Spotify. Aby Ivy rozpoznała pełne albumy, użyj stylu „artistalbum”. W przypadku piosenek użyj stylu „wykonawcy”.

Informacje o fragmencie: jest on oparty na oryginalnej odpowiedzi Michaela Smitha, ale jest nieco bardziej niezawodny. Wprowadziłem następujące ulepszenia:

  • Działa na listach odtwarzania, a także w bibliotece. Brakujące kolumny są ignorowane, a kolejność ustalona, ​​więc powinna działać na prawie każdej liście utworów w Google Music.

  • Zatrzymuje się, gdy osiągnie dno (wykryje pozycję przewijania) lub po upływie określonego czasu. Przekroczono limit czasu, aby zapobiec niekończącej się pętli w przypadku, gdy kod wykrywania przewijania jest wyłączony o kilka pikseli.

  • Jest znacznie szybszy (interwał co 1ms), ale czeka, jeśli dane nie będą gotowe (do określonego limitu czasu, obecnie 3s).

  • Wykonuje deduplikację podczas działania i na wyjściu.

  • Zbiera oceny: „niezdefiniowany” nigdy nie jest oceniany, „0” nie jest oceniany (tzn. Raz oceniany, ale następnie usuwany), „1” oznacza kciuk w dół, a „5” jest kciuk w górę (lubiany).

Oprócz podstawowych ulepszeń ładnie formatuje tekst i kopiuje go do schowka. Możesz także pobrać dane jako CSV, jeśli chcesz, uruchamiając songsToTextfunkcję po raz drugi.

Alternatywy:

  1. Jeśli potrzebujesz interfejsu API języka Python, sprawdź nieoficjalny projekt interfejsu Google Music API .

  2. Jeśli masz mnóstwo list odtwarzania i chcesz wyeksportować je wszystkie za jednym razem, wypróbuj eksportera list odtwarzania gmusic-scripts, który może to zrobić (Python, używa nieoficjalnego projektu API).


Hej, tylko kontynuacja kodu: powoduje skopiowanie tylko 30 ostatnich utworów, a kiedy robię songsToText („artistongong”), wyświetla długość w minutach: sekundach i numer ścieżki na liście odtwarzania. szczegóły piosenek są w każdym razie, ale jest ich tylko 30 (mam listy odtwarzania z setkami)
mkln

bez względu na liczbę utworów, nie utknął przy 30. Ale na innej liście odtwarzania ze 130 utworami eksportuje tylko pierwsze 117.
mkln

@mkln Zaktualizowałem kod, teraz obsługuje bibliotekę, listy odtwarzania oraz każdą inną listę utworów w Google Music. Po prostu uruchom wszystko, a skopiuje listę odtwarzania / bibliotekę / listę jako listę tekstową do schowka. Jeśli potrzebujesz wersji CSV, która zawiera wszystko (liczba odtworzeń, czas trwania, ocena), uruchom songsToText("all", true)później.
jmiserez

działa świetnie, dzięki. Próbuję napisać skrypt w języku Python, który zapisuje wszystkie listy odtwarzania. jak kliknąłbyś różne listy odtwarzania za pomocą javascript? czy możliwe byłoby posiadanie selektora listy odtwarzania na początku funkcji?
mkln

1
@mkln Ten facet już to zrobił: github.com/soulfx/gmusic-playlist Prawdopodobnie najłatwiej, jeśli użyjesz jego skryptu w języku Python! Do tej pory tego nie widziałem, ale prawdopodobnie jest to lepsza opcja, jeśli potrzebujesz więcej niż jednej listy odtwarzania.
jmiserez

18

Jeśli nie masz nic przeciwko uruchomieniu odrobiny kodu javascript w konsoli programisty przeglądarki, możesz wyodrębnić informacje ze strony w ten sposób (testowane tylko w 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); 
}

Spowoduje to wydrukowanie na konsoli listy większości aktualnie widocznych utworów w oknie. Musisz przewinąć w dół i uruchomić go ponownie, aby uzyskać więcej. W tej chwili nie wymyśliłem jeszcze przyzwoitego sposobu na zdobycie informacji w całości, ale ten szybki 5-minutowy hack jest lepszy niż nic.


To wygląda obiecująco. Spróbuję.
ale

2
Dziękuję bardzo za tę odpowiedź. Zaoszczędziłeś mi godziny i godziny. To, co zrobiłem, to ciągłe uruchamianie skryptu na liście odtwarzania, którą chciałem skopiować. Wklej wyniki do aplikacji Mac o nazwie Text Soap. Zmienił się w ",". Usunięto duplikaty i wyeksportowano jako txt. Następnie zmieniłem go na CSV, usunąłem nieposadzone kolumny i zaimportowałem do Spotify za pomocą: ivyishere.org W sumie zajęło mi to około 8 minut, po raz pierwszy zrozumiałem, okrzyki ~

Nie ma problemu, chętnie pomożemy.
darkliquid

Wygląda na to, że to załatwi sprawę. Moim największym problemem jest rozmiar moich list odtwarzania - 180 w stosunku do tego, który próbuję wyeksportować. Poradziłem sobie z tym trochę, maksymalizując okno Chrome, a następnie pomniejszając tak daleko, jak tylko mogłem. Gdybym tylko przekonał Chrome do powiększenia do 10%, miałbym to wszystko na jednym ekranie ... przy 25% zajęłoby to dwie rundy plus trochę więcej. (Czy jest szansa, że ​​możesz powiększyć JS?)
RobertB

1
Do Twojej wiadomości, jeśli masz tylko jeden element, użyj querySelector(...)zamiastquerySelectorAll(...)[0]
ThiefMaster

3

Korzystając z najwyższej odpowiedzi (w tym czasie) i szukając kompletnego rozwiązania, stworzyłem następujący kod, który przewija listę muzyki i dodaje obiekty JSON do tablicy w miarę jej działania.

Ze względu na to, że nie wiem dokładnie, jakie utwory są widoczne, kod dodaje je wszystkie, a następnie na końcu usuwa duplikaty. (Testowane tylko w Chrome).

Aby użyć: przejdź do swojej biblioteki, gdzie znajduje się pełna lista utworów i uruchom

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

Gdy dojdzie do dolnej części strony, uruchom to, aby zatrzymać przewijanie, usuń duplikat tablicy i skopiuj JSON do schowka.

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

Mam trochę krótszy JavaScript, który możesz wkleić do konsoli. Zamiast ponownie uruchamiać kod, możesz po prostu przewinąć w dół i dodać wszystkie wyświetlane albumy. Następnie możesz pobrać listę odtwarzania jako arkusz kalkulacyjny.

Instrukcje

  1. Idź tutaj: https://play.google.com/music/listen#/ap/auto-playlist-thumbs-up

  2. Otwórz Narzędzia programistyczne (F12) i wklej poniższy kod na karcie Konsola

  3. Przewiń, aby każdy album na liście odtwarzania był widoczny przynajmniej raz

  4. Kliknij dwukrotnie gdzieś na stronie, aby pobrać export-google-play.csv

  5. Otwórz export-google-play.csvw programie Excel.

Kod

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

Wydajność

wprowadź opis zdjęcia tutaj

GitHub


2

Trochę zmodyfikowałem podejście do najlepszej odpowiedzi. Działa to dla mnie lepiej z metodą kopiowania / wklejania Ivy ( http://www.ivyishere.org/ivy ):

Krok 1 Otwórz żądaną listę odtwarzania z Google Music w Chrome i wklej ją do konsoli:

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

Powinno to spowodować wyświetlenie całej listy odtwarzania, a nie tylko jej fragmentu.

Krok 2 Wklej ten skrypt do konsoli:

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

Krok 3 Przejdź do Ivy, a kiedy przejdziesz do kroku 2, wybierz kartę Kopiuj / Wklej i wklej tam dane wyjściowe konsoli.

EDYTOWAĆ

Zaktualizowany skrypt sugerowany przez Alexa Pedersena

Iteracja na temat udoskonalenia samurauturetskys (nie mam jeszcze wystarczającej reputacji, aby skomentować jego post). Wydaje mi się, że styl Googleplay został zaktualizowany, więc poniższy skrypt ponownie daje całkiem niezły wynik.

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


-2

Właśnie natrafiłem na to pytanie, szukając czegoś podobnego.

Chyba najlepszą opcją jest:

  1. zainstaluj aplikację taką jak „Kopia zapasowa listy odtwarzania”
  2. Za pomocą tej aplikacji wyeksportuj listę odtwarzania Google Music do pliku tekstowego.
  3. Zmień nazwę na .m3u za pomocą aplikacji FileManager (np. Ghost Commander)
  4. Otwórz listę odtwarzania za pomocą innej aplikacji, która ma więcej opcji (np. MusiXMatch).

1
Zakładam, że masz na myśli tę aplikację . Nie dobrze. Chociaż mam urządzenie z Androidem, nie szukam rozwiązania dla Androida. Ponadto wypróbowałem tę aplikację i nie może ona eksportować danych na ścieżkach, które nie są w urządzeniu, więc jest to dla mnie bezużyteczne.
ale

1
Oliver, będąc aplikacjami internetowymi, wolimy odpowiedzi, które nie wymagają aplikacji natywnych.
Vidar S. Ramdal,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.