Back to Deck
[snippet]
Экспорт понравившихся треков YouTube Music
ИСХОДНИК YouTube Music
ВЕРСИЯ 1.0.0
АВТОР Cododel
Одноразовый скрипт для консоли браузера на странице плейлиста Понравившаяся музыка в YouTube Music. Он прокручивает список, собирает видимые пары «исполнитель — название» и после завершения показывает кнопки копирования и скачивания .txt.
Как использовать
- Откройте плейлист Понравившаяся музыка на
music.youtube.comи дождитесь появления первых треков. - Откройте консоль разработчика браузера, вставьте весь код ниже и запустите его.
- Оставьте вкладку открытой, пока скрипт прокручивает список. После завершения скопируйте или скачайте результат кнопкой на экране.
- Чтобы остановить сбор раньше, выполните в консоли
window.__stopScraper = true. Уже собранные треки сохранятся.
В результате каждая строка имеет вид Исполнитель — Название. Одинаковые пары удаляются. Скрипт останавливается примерно через десять секунд без новых уникальных пар, поэтому при медленной загрузке плейлиста проверьте число собранных треков. Он читает текущую разметку страницы; изменения интерфейса YouTube Music могут повлиять на результат.
Исходный код
// YouTube Music Liked Songs Scraper & Exporter;(async () => { window.__stopScraper = false const tracks = new Set() let lastSize = 0 let stagnantTurns = 0 const maxStagnant = 12
console.log('🚀 Scraping started. Please wait while the playlist scrolls to the end...') console.log('ℹ️ To stop early, run: window.__stopScraper = true;')
while (stagnantTurns < maxStagnant && !window.__stopScraper) { // Collect tracks from currently mounted DOM nodes in the virtual list document.querySelectorAll('ytmusic-responsive-list-item-renderer').forEach((row) => { const title = row.querySelector('.title')?.innerText?.trim() const artist = row.querySelector('.secondary-flex-columns')?.innerText?.split('•')[0]?.trim() if (title && artist) tracks.add(`${artist} — ${title}`) })
if (tracks.size === lastSize) { stagnantTurns++ } else { stagnantTurns = 0 lastSize = tracks.size console.log(`Unique tracks collected: ${tracks.size}`) }
// Scroll to the last mounted element to trigger the next batch const items = document.querySelectorAll('ytmusic-responsive-list-item-renderer') if (items.length) { items[items.length - 1].scrollIntoView({ behavior: 'instant', block: 'end' }) } window.scrollTo(0, document.documentElement.scrollHeight)
await new Promise((res) => setTimeout(res, 850)) }
const result = Array.from(tracks).join('\n') window.__collectedTracks = result
// DevTools provides copy() in some browsers try { copy(result) } catch (e) {}
document.getElementById('ytm-scraper-result')?.remove() const banner = document.createElement('div') banner.id = 'ytm-scraper-result' banner.style.cssText = ` position: fixed; top: 20px; right: 20px; z-index: 999999; background: #181818; color: #fff; border: 2px solid #ff0000; border-radius: 12px; padding: 16px 20px; font-family: sans-serif; box-shadow: 0 10px 30px rgba(0,0,0,0.8); display: flex; flex-direction: column; gap: 10px; ` banner.innerHTML = ` <div style="font-size: 15px; font-weight: bold; color: #4ade80;"> ✅ Scraping complete! Found: ${tracks.size} tracks </div> <div style="display: flex; gap: 8px;"> <button id="ytm-copy-btn" style=" background: #ff0000; color: #fff; border: none; border-radius: 6px; padding: 8px 14px; font-weight: bold; cursor: pointer;"> 📋 Copy to clipboard </button> <button id="ytm-dl-btn" style=" background: #333; color: #fff; border: 1px solid #555; border-radius: 6px; padding: 8px 14px; cursor: pointer;"> 💾 Download .txt </button> <button id="ytm-close-btn" style=" background: transparent; color: #888; border: none; padding: 8px; cursor: pointer;"> ✕ </button> </div> `
document.body.appendChild(banner)
document.getElementById('ytm-copy-btn').onclick = async () => { const btn = document.getElementById('ytm-copy-btn') try { await navigator.clipboard.writeText(window.__collectedTracks) btn.innerText = 'Copied! ✓' btn.style.background = '#16a34a' } catch (error) { btn.innerText = 'Copy failed — use Download .txt' console.error('Clipboard copy failed:', error) } }
document.getElementById('ytm-dl-btn').onclick = () => { const blob = new Blob([window.__collectedTracks], { type: 'text/plain;charset=utf-8' }) const url = URL.createObjectURL(blob) const a = document.createElement('a') a.href = url a.download = `liked_tracks_${tracks.size}.txt` a.click() setTimeout(() => URL.revokeObjectURL(url), 1000) }
document.getElementById('ytm-close-btn').onclick = () => banner.remove()
console.log( `🎉 Done! Collected ${tracks.size} tracks. Use the on-screen buttons to copy or download.`, )})()