พิมพ์เพลย์ลิสต์จาก Google Play Music


43

ฉันต้องการพิมพ์รายชื่อเพลง (กับศิลปิน, อัลบั้ม, การให้คะแนนและถ้าเป็นไปได้จำนวนการเล่นและระยะเวลา) จากบัญชีGoogle Play Musicของฉัน

ไม่มีวิธีง่ายๆในการทำสิ่งนี้จากแอป การทำหน้าจอการพิมพ์ในขณะที่ฉันเลื่อนดูรายการเพลงที่ยาวไม่สามารถใช้การได้

ฉันยินดีที่จะส่งออกข้อมูลไปยังรูปแบบมาตรฐาน (ข้อความธรรมดา, CSV, XML, ฯลฯ ) ที่ฉันสามารถจัดการกับตัวเองได้

ข้อเสนอแนะใด ๆ


นี้มีนำฉันไปยังสร้างวิธีการสำหรับการมองเห็นเพลงที่ไม่ได้อยู่ใน Google Play เพลย์ลิสและเห็นว่าที่ Google รายการเพลงเล่นเพลงที่อยู่ในโดยอัตโนมัติ
Zach Saucier

คำตอบ:


17

การแก้ไขคำตอบของ darkliquidฉันได้ทำสิ่งต่อไปนี้ซึ่งช่วยให้สามารถบันทึกเพลย์ลิสต์ได้หลายรายการพร้อมกัน

คำแนะนำ:

  1. ไปที่หน้ารายการของคุณ
  2. วางรหัส JavaScript ด้านล่างลงในคอนโซลของคุณ
  3. คลิกที่เพลย์ลิสต์ที่คุณต้องการบันทึกเป็นข้อความ
  4. เมื่ออยู่ในหน้าเพลย์ลิสต์ให้เลื่อนไปที่ด้านล่างค่อนข้างช้า
  5. หลังจากที่คุณเลื่อนไปที่ด้านล่างนำทางกลับไปที่หน้าเพลย์ลิสต์ (เช่นเดียวกับในขั้นตอนที่ 1) โดยใช้เมนูหรือปุ่มย้อนกลับเบราว์เซอร์ของคุณ
  6. ทำซ้ำขั้นตอนที่ 3-5 สำหรับเพลย์ลิสต์ทั้งหมดที่คุณต้องการบันทึกเป็นข้อความ
  7. เมื่อคุณทำเช่นนี้ทุกรายการเพลงที่คุณต้องการจะบันทึกลงในข้อความคุณทั้งสองประเภทสามารถJSON.stringify(tracklistObj, null, '\t')(เปลี่ยน'\t'ไป' 'ถ้าคุณต้องการเยื้องน้อยที่สุด) หรือtracklistObjถ้าคุณเพียงต้องการวัตถุ JavaScript เพื่อจัดการกับมันทางของคุณเอง หากคุณต้องการให้เรียงลำดับให้รันคำสั่ง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;

คุณยังสามารถพิมพ์ชื่อแทร็กไปยังคอนโซลได้โดยเปลี่ยนprintTracksToConsoleเป็นtrue(คุณควรทำก่อนขั้นตอนที่ 3)

โปรดทราบว่าคุณอาจละเว้นข้อผิดพลาด GET และ POST ทั้งหมดในคอนโซล (สิ่งเหล่านี้สร้างขึ้นโดย Play Music เองไม่ใช่สคริปต์นี้)

นอกจากนี้ยังทราบว่าขณะนี้การติดตั้งก็เพียงเพื่อให้Artist - Track nameแต่คุณสามารถแก้ไขบรรทัดที่มีtracklistObj[currentPlaylist].push(artist + " - " + title);กับalbum, playCount, durationหรือrating, และ / หรือสิ่งที่รูปแบบที่คุณต้องการ (รวมทั้งรูปแบบ CSV ถ้าคุณดังนั้นโปรด)

ตัวอย่างผลลัพธ์ (เพลย์ลิสต์ Google Play ทั้งหมดที่ฉันมี) ด้วยการตั้งค่าเริ่มต้น ทั้งหมดใช้เวลาประมาณ 5 นาทีเพื่อนำทางไปยังเพลย์ลิสต์ทั้ง 32 รายการเลื่อนลงจากนั้นแปลงผลลัพธ์เป็นข้อความ

ป.ล. คุณอาจสนใจใช้เว็บไซต์ที่ฉันเรียกว่าTune My Musicเพื่อสร้างเพลย์ลิสต์ YouTube (แต่ YouTube จำกัด การสร้างเพลย์ลิสต์ถึง 10 ต่อวัน) จากผลลัพธ์เพื่อให้เพื่อนของคุณสามารถฟัง Google Playlist ของคุณ หากคุณทำสิ่งนี้คุณอาจต้องการใช้บางอย่างเช่นTextMechanicเพื่อลบเครื่องหมายคำพูดและ.mp3จากรายการเอาท์พุท


1
หากมีวิธีที่ดีกว่าในการทำเช่นนี้แทนที่จะวาง JavaScript ในคอนโซล (ฉันยังมีอาการสะอึกเล็กน้อยตั้งแต่ Ublock Origin บล็อกสคริปต์) แต่นี่คือสิ่งที่ฉันต้องการ
เบียร์

ฉันเกรงว่ามันล้าสมัยแล้ว :( TypeError: ไม่สามารถอ่านคุณสมบัติ 'รวมถึง' ที่ไม่ได้กำหนดที่ getVisibleTracks (<anonymous>: 20: 43) ที่ <anonymous>: 49: 5 ที่ c ( play-music.gstatic.com/ fe / 6..e / listen__en_gb.js: 1190: 211 )
FloriOn

4
@FloriOn ขอบคุณสำหรับการแสดงความคิดเห็น! ฉันอัปเดตรหัสเพื่อให้มันทำงานอีกครั้งในขณะนี้
Zach Saucier

2
@ ทะเลมี คุณสามารถเปลี่ยนรหัสให้เป็น bookmarklet
David Metcalfe

ข้อผิดพลาดของคอนโซลปรากฏขึ้นเมื่อเรียกใช้รหัสนี้ แต่ดูเหมือนว่าจะไม่ปิดกั้นไม่ให้ทำงาน
Otheus

31

(อัปเดตเมื่อวันที่ 2016-05-09 แข็งแกร่งกว่าคำตอบยอดนิยมปัจจุบัน)

หากคุณต้องการบันทึกเพลย์ลิสต์เพียงไม่กี่คุณก็สามารถใช้ข้อมูลโค้ด Javascript ของฉันด้านล่าง ตัวอย่างนี้สามารถบันทึกทุกรายการตามที่ปรากฏบนหน้าเว็บดังนั้นจึงเหมาะสำหรับมุมมองไลบรารีเพลง / อัลบั้ม / ศิลปินทั้งหมด ฉันได้แสดงอีกสองทางเลือกในตอนท้ายของคำตอบนี้

  1. ไปที่: https://play.google.com/music/listen#/all (หรือเพลย์ลิสต์ของคุณ)

  2. เปิดคอนโซลนักพัฒนาซอฟต์แวร์ (F12 สำหรับ Chrome) วางรหัสด้านล่างลงในคอนโซล

  3. เพลงที่คัดลอกมาทั้งหมดจะถูกเก็บไว้ในallsongsวัตถุและคัดลอกรายการข้อความไปยังคลิปบอร์ด ฉันขอแนะนำให้ทำงาน songsToText("all",true)หลังจากนั้นเพื่อรับข้อมูล CSV ทั้งหมด เรียกใช้copy(outText)ด้วยตนเองหากการคัดลอกคลิปบอร์ดไม่ทำงานในครั้งแรก

รหัส (เวอร์ชั่นล่าสุด 10 พฤษภาคม 2559, 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);

รหัสล่าสุดบน Github (สรุปสาระสำคัญ) ที่นี่: https://gist.github.com/jmiserez/c9a9a0f41e867e5ebb75

  • หากคุณต้องการเอาต์พุตในรูปแบบข้อความสามารถเรียกใช้ฟังก์ชั่น songsToText () คุณสามารถเลือกสไตล์เลือกรูปแบบและหากควรส่งออกเพลงที่ชอบ / ยกนิ้ว รายการผลลัพธ์จะถูกวางลงในคลิปบอร์ด รูปแบบที่มีall, artist, artistalbum, ,artistsong artistalbumsongCSV จะส่งผลให้เป็นไฟล์ CSV และสามารถปล่อยออกไป (ค่าเริ่มต้นเป็นเท็จ) Likedonly สามารถถูกปล่อยออกมา (ค่าเริ่มต้นเป็นเท็จ) หรือตั้งค่าเป็นจริงและจะกรองเพลงทั้งหมดที่มีคะแนนมากกว่าหรือเท่ากับ 5 เช่น:

    • songsToText("all",true,false) จะส่งออกเพลงทั้งหมดในรูปแบบ csv
    • songsToText("all",true,true) จะส่งออกเฉพาะเพลงที่ชอบในรูปแบบ CSV
    • songsToText("artistsong",false,false) จะส่งออกเพลงทั้งหมดเป็นข้อความ
  • จากนั้นคุณสามารถวางข้อมูลได้ทุกที่ที่คุณต้องการตัวอย่างเช่นhttp://www.ivyishere.org/หากคุณต้องการเพิ่มเพลงหรืออัลบั้มลงในบัญชี Spotify ของคุณ ในการทำให้ Ivy รู้จักอัลบั้มเต็มให้ใช้สไตล์ "artistalbum" สำหรับเพลงให้ใช้สไตล์ "artistong"

เกี่ยวกับตัวอย่าง: สิ่งนี้ขึ้นอยู่กับคำตอบดั้งเดิมของ Michael Smith แต่ค่อนข้างแข็งแกร่ง ฉันได้ทำการปรับปรุงต่อไปนี้:

  • ทำงานบนเพลย์ลิสต์เช่นเดียวกับห้องสมุด คอลัมน์ใด ๆ ที่ขาดหายไปจะถูกละเว้นและคำสั่งจะถูกคิดออกดังนั้นควรทำงานกับเกือบทุกรายการเพลงใน Google Music

  • มันหยุดอย่างใดอย่างหนึ่งเมื่อมันมาถึงด้านล่าง (ตรวจจับตำแหน่งการเลื่อน) หรือหลังจากหมดเวลาที่ระบุ หมดเวลาใช้งานเพื่อป้องกันการวนซ้ำไม่สิ้นสุดในกรณีที่โค้ดตรวจจับการเลื่อนถูกปิดด้วยพิกเซลไม่กี่พิกเซล

  • มันเร็วกว่ามาก (ช่วงทุก 1 มิลลิวินาที) แต่รอถ้าข้อมูลยังไม่พร้อม (ขึ้นอยู่กับการหมดเวลาที่ระบุในปัจจุบันคือ 3 วินาที)

  • ทำการขจัดข้อมูลซ้ำซ้อนระหว่างการดำเนินการและบนเอาต์พุต

  • รวบรวมการจัดอันดับ: "ไม่ได้กำหนด" ไม่เคยถูกจัดอันดับ "0" ไม่ได้รับการจัดอันดับ (เช่นเมื่อถูกจัดอันดับ แต่ถูกลบออกแล้ว) "1" จะถูกเลื่อนลงและ "5" จะถูกยกระดับ (ชอบ)

นอกเหนือจากการปรับปรุงพื้นฐานแล้วยังจัดรูปแบบข้อความอย่างดีและคัดลอกไปยังคลิปบอร์ด คุณยังสามารถรับข้อมูลเป็น CSV ได้หากต้องการโดยเรียกใช้songsToTextฟังก์ชันเป็นครั้งที่สอง

ทางเลือก:

  1. หากคุณต้องการหลาม API ตรวจสอบAPI Google Music ทางการโครงการ

  2. หากคุณมีเพลย์ลิสต์จำนวนมากและต้องการส่งออกทั้งหมดในครั้งเดียวลองผู้ส่งออกเพลย์ลิสต์gmusic-สคริปต์ที่สามารถทำได้ (Python ใช้โครงการ API ที่ไม่เป็นทางการ)


นี่เป็นเพียงการติดตามรหัส: มันจะส่งผลให้มีเพียง 30 เพลงที่ถูกคัดลอกและเมื่อฉันทำเพลง ToText ("artistong") มันจะแสดงความยาวเป็นนาที: วินาทีและหมายเลขแทร็กในเพลย์ลิสต์ รายละเอียดเพลงอยู่ในทุกเพลงแล้ว แต่มีเพียง 30 คน (ฉันมีเพลย์ลิสต์นับร้อย)
mkln

ไม่เป็นไรกับจำนวนเพลงก็ไม่ได้ติดอยู่ที่ 30 แต่ในอีกเพลย์ลิสต์ที่มี 130 เพลงมันส่งออกเพียง 117 เพลงแรกเท่านั้น
mkln

@mkln ฉันได้อัปเดตรหัสแล้วตอนนี้มันจัดการไลบรารีเพลย์ลิสต์รวมถึงรายการเพลงอื่น ๆ ใน Google Music เพียงแค่รันทุกอย่างและมันจะคัดลอกเพลย์ลิสต์ / ไลบรารี / รายการเป็นรายการข้อความไปยังคลิปบอร์ด หากคุณต้องการเวอร์ชัน CSV ที่รวมทุกอย่าง (จำนวนการเล่นระยะเวลาการจัดอันดับ) ให้เรียกใช้songsToText("all", true)หลังจากนั้น
jmiserez

มันใช้งานได้ดีขอบคุณ ฉันพยายามเขียนสคริปต์หลามที่บันทึกเพลย์ลิสต์ทั้งหมด คุณจะคลิกที่เพลย์ลิสต์ต่างๆผ่านทางจาวาสคริปต์ได้อย่างไร เป็นไปได้ไหมที่จะมีตัวเลือกเพลย์ลิสต์ที่จุดเริ่มต้นของฟังก์ชั่น
mkln

1
@mkln เอ่อคนนี้ทำไปแล้ว: github.com/soulfx/gmusic-playlistน่าจะง่ายที่สุดถ้าคุณใช้สคริปต์ Python ของเขา! ฉันไม่ได้เห็นสิ่งนี้มาจนถึงตอนนี้ แต่อาจเป็นตัวเลือกที่ดีกว่าถ้าคุณต้องการเพลย์ลิสต์มากกว่าหนึ่งรายการ
jmiserez

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 นาทีนี้ดีกว่าไม่มีอะไรเลย


สิ่งนี้ดูมีแนวโน้ม ฉันจะไปเอง
เบียร์

2
ขอบคุณมากสำหรับคำตอบนี้ คุณช่วยฉันชั่วโมงและเวลา สิ่งที่ฉันทำคือเรียกใช้สคริปต์ของคุณซ้ำแล้วซ้ำอีกในเพลย์ลิสต์ที่ฉันต้องการคัดลอก วางผลลัพธ์ลงในแอป Mac ชื่อ Text Soap เปลี่ยน --- เป็น "," ลบรายการที่ซ้ำกันและส่งออกเป็น txt จากนั้นเปลี่ยนเป็น CSV ดึงคอลัมน์ที่ไม่ได้แยกออกและนำเข้ามาที่ Spotify โดยใช้: ivyishere.orgทั้งหมดใช้เวลาประมาณ 8 นาทีที่ฉันได้แฮงค์มันไชโย ~

ไม่มีปัญหายินดีให้ความช่วยเหลือ
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.csvใน 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);

เอาท์พุต

ป้อนคำอธิบายรูปภาพที่นี่

GitHub


2

ฉันปรับเปลี่ยนวิธีการของคำตอบยอดนิยมเล็กน้อย วิธีนี้ใช้ได้ผลดีกว่าสำหรับฉันด้วยวิธีการคัดลอก / วางของ Ivy ( http://www.ivyishere.org/ivy ):

ขั้นตอนที่ 1เปิดเพลย์ลิสต์ที่คุณต้องการจาก Google Music ใน Chrome และวางสิ่งนี้ลงในคอนโซล:

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ไปที่Ivyและเมื่อคุณไปถึงขั้นตอนที่ 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);


-2

ฉันเพิ่งเจอคำถามนี้มองหาสิ่งที่คล้ายกัน

ฉันเดาตัวเลือกที่ดีที่สุดของคุณคือ:

  1. ติดตั้งแอพเช่น "Playlist Backup"
  2. ส่งออก Google Music Playlist ไปยัง textfile ด้วยแอพนี้
  3. เปลี่ยนชื่อเป็น. m3u ด้วยแอพ FileManager (เช่น Ghost Commander)
  4. เปิดเพลย์ลิสต์ด้วยแอพอื่นที่มีตัวเลือกเพิ่มเติม (เช่น MusiXMatch)

1
ฉันถือว่าคุณหมายถึงแอพนี้ ไม่ดี. ในขณะที่ฉันมีอุปกรณ์ Android ฉันไม่ได้มองหาโซลูชัน Android เพิ่มเติมฉันได้ลองใช้แอพนี้และไม่สามารถส่งออกข้อมูลบนแทร็กที่ไม่ได้อยู่ในอุปกรณ์ดังนั้นมันจึงไร้ประโยชน์สำหรับฉัน
เบียร์

1
Oliver ในฐานะ Web Applications เราต้องการคำตอบที่ไม่ต้องการแอพพื้นฐาน
Vidar S. Ramdal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.