您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds an export button to the subscriptions section of the sidebar, which generates an OPML file of RSS feeds for your subscriptions.
当前为
// ==UserScript== // @name Export YouTube Subscriptions to RSS OPML // @namespace https://github.com/theborg3of5/Userscripts/ // @version 1.2 // @description Adds an export button to the subscriptions section of the sidebar, which generates an OPML file of RSS feeds for your subscriptions. // @author Gavin Borg // @match https://www.youtube.com/ // ==/UserScript== function addButton() { var buttonParent = findSpotToPutButton(); // Create and insert button var button = document.createElement("button"); button.title = "Export subscriptions as OPML file for RSS readers. Make sure to expand subscriptions in sidebar first."; button.innerHTML = "Export"; button.style.fontWeight = "bold"; button.style.float = "right"; button.style.marginBottom = "2px"; button.style.marginRight = "30px"; button.id = "exportOPMLButton"; button.addEventListener("click", exportSubscriptions); buttonParent.appendChild(button); } function findSpotToPutButton() { var sectionLabels = document.querySelectorAll("yt-formatted-string#guide-section-title"); // First try to find the "Subscriptions" section. Won't work outside of an en-US locale. var subscriptionsText = "Subscriptions"; for(var i = 0; i < sectionLabels.length; i++) { if(sectionLabels[i].innerHTML === subscriptionsText) { return sectionLabels[i].parentElement; } } // If that fails, just put it in the second section (first one's header is hidden). return sectionLabels[1].parentElement; } function exportSubscriptions() { var channels = []; var inChannels = false; var channelURLFragment = "www.youtube.com/channel/"; var links = document.querySelectorAll("div#items a#endpoint[href]"); // Sidebar links for(var i = 0; i < links.length; i++) { var href = links[i].href; var title = links[i].getAttribute("title"); if(href.indexOf(channelURLFragment) > -1) { // Found our first channel inChannels = true; } if(inChannels) { if(href.indexOf(channelURLFragment) === -1) { // Once we're in the channels block, any link that's not to a channel means we've exited it and are finished. break; } var channelId = href.substring(href.lastIndexOf(channelURLFragment) + channelURLFragment.length, href.length); if(channelId.indexOf("/") > -1) { channelId = channelId.substring(0, channelId.indexOf("/")) // Sometimes the link doesn't end with the ID, but with other stuff like "/videos" - trim that off. } channels.push({"title":title, "id":channelId}); } } // Build download link and click it var xml = buildXML(channels); var fileType = "text/plain"; var blob = new Blob([xml], {type: fileType}); var blobURL = window.URL.createObjectURL(blob); var filename = "youtubeSubscriptions.opml"; var downloadLink = document.createElement("a"); downloadLink.setAttribute("href", blobURL); downloadLink.setAttribute("download", filename); downloadLink.dataset.downloadurl = fileType + ":" + filename + ":" + blobURL; downloadLink.click(); } function buildXML(channels) { // Goal structure: // <opml version="1.0"> // <head> // <title>YouTube Subscriptions as RSS</title> // </head> // <body> // <outline text="YouTube Subscriptions" title="YouTube Subscriptions"> // <outline type="rss" text="" title="" xmlURL="" /> // ... // </outline> // </body> // </opml> var xmlDoc = document.implementation.createDocument("", "", null); var opml = xmlDoc.createElement("opml"); opml.setAttribute("version", "1.0"); var head = xmlDoc.createElement("head"); var title = xmlDoc.createElement("title"); title.innerHTML = "YouTube Subscriptions as RSS"; head.appendChild(title); opml.appendChild(head); var body = xmlDoc.createElement("body"); var parentOutline = xmlDoc.createElement("outline"); parentOutline.setAttribute("text", "YouTube Subscriptions") parentOutline.setAttribute("title", "YouTube Subscriptions") for(var j = 0; j < channels.length; j++) { var outline = xmlDoc.createElement("outline"); outline.setAttribute("type", "rss"); outline.setAttribute("text", channels[j].title); outline.setAttribute("title", channels[j].title); outline.setAttribute("xmlUrl", "https://www.youtube.com/feeds/videos.xml?channel_id=" + channels[j].id); parentOutline.appendChild(outline); } body.appendChild(parentOutline); opml.appendChild(body); xmlDoc.appendChild(opml); var s = new XMLSerializer(); return s.serializeToString(xmlDoc); } window.onload = addButton;