您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
获取B站收藏夹和合集内所有视频的链接(直接解析网页)
// ==UserScript== // @license MIT // @name B站收藏夹与合集视频链接批量获取 // @namespace http://tampermonkey.net/ // @version 1.1 // @description 获取B站收藏夹和合集内所有视频的链接(直接解析网页) // @author Claude // @match https://space.bilibili.com/*/favlist* // @match https://space.bilibili.com/*/lists/* // @grant none // ==/UserScript== (function() { 'use strict'; // 存储所有收集到的视频 let allVideos = []; // 创建主面板 const container = document.createElement('div'); container.className = 'bili-link-collector'; container.innerHTML = ` <style> .bili-link-collector { position: fixed; top: 100px; right: 20px; z-index: 10000; width: 320px; font-family: "Microsoft YaHei", "Segoe UI", Arial, sans-serif; } .bili-link-collector * { box-sizing: border-box; } .bili-collect-btn { width: 100%; padding: 10px 15px; background-color: #FB7299; color: white; border: none; border-radius: 4px; font-size: 14px; font-weight: bold; cursor: pointer; box-shadow: 0 2px 4px rgba(0,0,0,0.1); transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; } .bili-collect-btn:hover { background-color: #fc8bab; box-shadow: 0 4px 8px rgba(0,0,0,0.15); } .bili-collect-btn svg { margin-right: 8px; } .bili-result-panel { margin-top: 10px; background-color: white; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); overflow: hidden; display: none; max-height: 70vh; display: flex; flex-direction: column; } .bili-result-header { background-color: #F6F7F8; padding: 12px 15px; border-bottom: 1px solid #E5E9EF; display: flex; justify-content: space-between; align-items: center; } .bili-result-title { font-size: 14px; font-weight: bold; color: #18191C; display: flex; align-items: center; } .bili-result-counter { margin-left: 6px; background-color: #FB7299; color: white; border-radius: 10px; padding: 1px 6px; font-size: 12px; } .bili-result-actions { display: flex; gap: 8px; } .bili-action-btn { padding: 4px 8px; border-radius: 4px; border: 1px solid #E5E9EF; background-color: white; color: #61666D; font-size: 12px; cursor: pointer; transition: all 0.2s ease; } .bili-action-btn:hover { background-color: #F6F7F8; color: #FB7299; border-color: #FB7299; } .bili-copy-20-btn { padding: 4px 8px; border-radius: 4px; border: 1px solid #FB7299; background-color: #FFF0F5; color: #FB7299; font-size: 12px; cursor: pointer; transition: all 0.2s ease; } .bili-copy-20-btn:hover { background-color: #FB7299; color: white; } .bili-result-list { overflow-y: auto; padding: 0; margin: 0; list-style: none; flex: 1; } .bili-result-item { padding: 12px 15px; border-bottom: 1px solid #E5E9EF; transition: background-color 0.2s ease; display: flex; align-items: center; gap: 10px; } .bili-result-item:hover { background-color: #F6F7F8; } .bili-result-item:last-child { border-bottom: none; } .bili-video-cover { width: 80px; height: 50px; border-radius: 4px; overflow: hidden; flex-shrink: 0; background-color: #F6F7F8; position: relative; } .bili-video-cover img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.3s ease; } .bili-result-item:hover .bili-video-cover img { transform: scale(1.05); } .bili-video-info { flex: 1; min-width: 0; } .bili-video-title { font-size: 14px; margin: 0; line-height: 1.4; } .bili-video-title a { color: #18191C; text-decoration: none; display: block; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } .bili-video-title a:hover { color: #FB7299; } .bili-tip { padding: 10px 15px; border-top: 1px solid #E5E9EF; color: #9499A0; font-size: 12px; text-align: center; } .bili-icon { display: inline-block; vertical-align: middle; } .bili-video-cover::after { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.03); pointer-events: none; } .bili-action-group { display: flex; flex-wrap: wrap; gap: 8px; } </style> <button class="bili-collect-btn"> <svg class="bili-icon" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7 1C7 0.447715 7.44772 0 8 0C8.55228 0 9 0.447715 9 1V15C9 15.5523 8.55228 16 8 16C7.44772 16 7 15.5523 7 15V1Z" fill="white"/> <path d="M1 9C0.447715 9 0 8.55228 0 8C0 7.44772 0.447715 7 1 7H15C15.5523 7 16 7.44772 16 8C16 8.55228 15.5523 9 15 9H1Z" fill="white"/> </svg> 获取当前页视频链接 </button> <div class="bili-result-panel"> <div class="bili-result-header"> <div class="bili-result-title">收集结果<span class="bili-result-counter">0</span></div> <div class="bili-action-group"> <button class="bili-copy-20-btn" id="bili-copy-20-btn">复制20条</button> <button class="bili-action-btn" id="bili-copy-btn">复制全部</button> <button class="bili-action-btn" id="bili-clear-btn">清空</button> </div> </div> <ul class="bili-result-list"></ul> <div class="bili-tip">提示:请手动翻页后再次点击获取按钮收集更多视频</div> </div> `; document.body.appendChild(container); const collectBtn = container.querySelector('.bili-collect-btn'); const resultPanel = container.querySelector('.bili-result-panel'); const resultList = container.querySelector('.bili-result-list'); const resultCounter = container.querySelector('.bili-result-counter'); const copyBtn = container.querySelector('#bili-copy-btn'); const copy20Btn = container.querySelector('#bili-copy-20-btn'); const clearBtn = container.querySelector('#bili-clear-btn'); // 点击按钮收集视频 collectBtn.addEventListener('click', function() { // 显示结果面板 resultPanel.style.display = 'flex'; try { // 获取视频 const videos = getVideosFromCurrentPage(); // 添加到总视频列表中(去重) videos.forEach(video => { if (!allVideos.some(v => v.bvid === video.bvid)) { allVideos.push(video); } }); // 更新显示 updateResultsDisplay(); } catch (error) { alert('获取视频失败: ' + error.message); } }); // 复制链接 copyBtn.addEventListener('click', function() { if (allVideos.length === 0) { alert('还没有收集到视频链接'); return; } const links = allVideos .map(video => `https://www.bilibili.com/video/${video.bvid}`) .join('\n'); // 使用Clipboard API或回退到execCommand copyToClipboard(links, '已复制所有视频链接到剪贴板!'); }); // 复制前20条并删除 copy20Btn.addEventListener('click', function() { if (allVideos.length === 0) { alert('还没有收集到视频链接'); return; } // 确定要复制的数量(最多20条,或者全部如果不足20条) const count = Math.min(20, allVideos.length); const videosToCopy = allVideos.slice(0, count); const links = videosToCopy .map(video => `https://www.bilibili.com/video/${video.bvid}`) .join('\n'); // 复制到剪贴板 copyToClipboard(links, `已复制前${count}条视频链接到剪贴板!`); // 从列表中删除已复制的视频 allVideos = allVideos.slice(count); // 更新显示 updateResultsDisplay(); }); // 清空结果 clearBtn.addEventListener('click', function() { allVideos = []; updateResultsDisplay(); }); // 通用复制到剪贴板函数 function copyToClipboard(text, successMessage) { try { navigator.clipboard.writeText(text).then(() => { alert(successMessage); }).catch(err => { fallbackCopy(text, successMessage); }); } catch (e) { fallbackCopy(text, successMessage); } } // 从当前页面获取视频 function getVideosFromCurrentPage() { // 检查页面类型 const isListPage = window.location.href.includes('/lists/'); // 尝试合集页面的视频卡片(list页面) if (isListPage) { // 尝试合集页特有的选择器 const seasonCards = document.querySelectorAll('.season-item'); if (seasonCards && seasonCards.length > 0) { return extractVideosFromElements(seasonCards); } const episodeItems = document.querySelectorAll('.ep-item'); if (episodeItems && episodeItems.length > 0) { return extractVideosFromElements(episodeItems); } } // 尝试B站最新收藏夹界面的视频卡片 const videoCards = document.querySelectorAll('.bili-video-card'); if (videoCards && videoCards.length > 0) { return extractVideosFromElements(videoCards); } // 尝试旧版收藏夹界面的视频项 const videoItems = document.querySelectorAll('.fav-video-list .small-item') || document.querySelectorAll('.content-list .small-item') || document.querySelectorAll('.favorite-list-content .favorite-video-item'); if (videoItems && videoItems.length > 0) { return extractVideosFromElements(videoItems); } // 如果上面的选择器都没找到,尝试找所有视频链接 const allLinks = Array.from(document.querySelectorAll('a[href*="/video/BV"]')); if (allLinks.length > 0) { return allLinks.map(link => { const href = link.href; const bvid = href.match(/\/video\/(BV[a-zA-Z0-9]+)/)?.[1] || ''; const title = link.textContent.trim() || link.getAttribute('title') || bvid; const imgElem = link.querySelector('img') || document.querySelector(`a[href*="${bvid}"] img`); const cover = imgElem ? (imgElem.src || imgElem.getAttribute('data-src')) : ''; return { bvid, title, cover }; }); } throw new Error('未找到视频元素,请确保你在收藏夹或合集页面上'); } // 从元素中提取视频信息 function extractVideosFromElements(elements) { const videos = []; elements.forEach(item => { try { // 获取视频链接 const linkElement = item.querySelector('a[href*="/video/BV"]'); if (!linkElement) return; const href = linkElement.href; const bvid = href.match(/\/video\/(BV[a-zA-Z0-9]+)/)?.[1]; if (!bvid) return; // 获取标题 - 优先查找新版B站的标题元素 const titleElement = item.querySelector('.bili-video-card__title') || item.querySelector('.title') || item.querySelector('.video-title') || item.querySelector('.ep-title') || item.querySelector('.season-title') || linkElement; const title = titleElement.textContent.trim() || titleElement.getAttribute('title') || bvid; // 获取封面 const imgElement = item.querySelector('.bili-video-card__cover img') || item.querySelector('.cover img') || item.querySelector('img.cover') || item.querySelector('.ep-cover img') || item.querySelector('.season-cover img') || item.querySelector('img') || document.querySelector(`a[href*="${bvid}"] img`); let cover = ''; if (imgElement) { cover = imgElement.src || imgElement.getAttribute('data-src') || ''; // 如果是懒加载图片 if (!cover && imgElement.dataset.src) { cover = imgElement.dataset.src; } // 如果是缩略图,尝试获取更大的图片 if (cover.includes('@') && !cover.includes('gif')) { cover = cover.split('@')[0]; } } videos.push({ bvid, title, cover }); } catch (e) { // 忽略单个视频解析错误 } }); return videos; } // 更新结果显示 function updateResultsDisplay() { // 更新计数 resultCounter.textContent = allVideos.length; // 清空当前列表 resultList.innerHTML = ''; // 添加视频项 allVideos.forEach(video => { const li = document.createElement('li'); li.className = 'bili-result-item'; const videoLink = `https://www.bilibili.com/video/${video.bvid}`; // 设置默认封面 let coverImg = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA4MCA1MCI+PHJlY3Qgd2lkdGg9IjgwIiBoZWlnaHQ9IjUwIiBmaWxsPSIjZWVlIi8+PHRleHQgeD0iNDAiIHk9IjI1IiBmb250LWZhbWlseT0iQXJpYWwsIHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGFsaWdubWVudC1iYXNlbGluZT0ibWlkZGxlIiBmaWxsPSIjOTk5Ij7npL7ljLrlm77niYc8L3RleHQ+PC9zdmc+'; if (video.cover) { coverImg = video.cover; } li.innerHTML = ` <div class="bili-video-cover"> <img src="${coverImg}" alt="${video.title}" loading="lazy" onerror="this.src='data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA4MCA1MCI+PHJlY3Qgd2lkdGg9IjgwIiBoZWlnaHQ9IjUwIiBmaWxsPSIjZWVlIi8+PHRleHQgeD0iNDAiIHk9IjI1IiBmb250LWZhbWlseT0iQXJpYWwsIHNhbnMtc2VyaWYiIGZvbnQtc2l6ZT0iMTIiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGFsaWdubWVudC1iYXNlbGluZT0ibWlkZGxlIiBmaWxsPSIjOTk5Ij7lm77niYfliqDovb3lpLHotKU8L3RleHQ+PC9zdmc+'"> </div> <div class="bili-video-info"> <h3 class="bili-video-title"> <a href="${videoLink}" target="_blank" title="${video.title}">${video.title}</a> </h3> </div> `; resultList.appendChild(li); }); // 根据是否有足够的视频更新复制20条按钮的状态 if (allVideos.length < 20) { copy20Btn.textContent = `复制${allVideos.length}条`; } else { copy20Btn.textContent = '复制20条'; } } // 备用复制方法 function fallbackCopy(text, successMessage) { const textarea = document.createElement('textarea'); textarea.value = text; textarea.style.position = 'fixed'; textarea.style.opacity = 0; document.body.appendChild(textarea); textarea.select(); try { const successful = document.execCommand('copy'); if (successful) { alert(successMessage); } else { alert('复制失败,请手动复制以下链接:\n' + text); } } catch (e) { alert('复制失败,请手动复制以下链接:\n' + text); } document.body.removeChild(textarea); } })();