您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在B站个人空间的投稿 - 图文界面,提供右键直接下载动态中的图片
当前为
// ==UserScript== // @name Bilibili动态预览图片下载 // @namespace BilibiliDynamicPreviewDownload // @license MIT // @version 0.9 // @description 在B站个人空间的投稿 - 图文界面,提供右键直接下载动态中的图片 // @author Kaesinol // @match https://space.bilibili.com/* // @grant GM_download // @require https://update.gf.qytechs.cn/scripts/473358/1237031/JSZip.js // ==/UserScript== (function () { "use strict"; const fetchJsonData = async (dynamicId) => { const apiUrl = `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail?dynamic_id=${dynamicId}`; try { const response = await fetch(apiUrl); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const jsonData = await response.json(); const cardData = JSON.parse(jsonData.data.card.card); const pictures = cardData.item.pictures?.map((p) => p.img_src.replace(/^http:/, "https:") ) || []; const uname = jsonData.data.card.desc.user_profile.info.uname; const uid = jsonData.data.card.desc.user_profile.info.uid; const fileName = `${uname} - ${uid} - ${dynamicId}`; console.log("提取的图片链接:", pictures); downloadFiles(pictures, fileName); } catch (error) { console.error("请求或解析失败:", error); } }; const downloadFiles = async (urls, fileName) => { if (urls.length > 1) { await createZipAndDownload(urls, fileName); } else { const promises = urls.map((url, index) => downloadFile(url, index, fileName) ); await Promise.all(promises); } }; const createZipAndDownload = async (urls, fileName) => { const zip = new JSZip(); const promises = urls.map((url, index) => { return fetch(url) .then((response) => { if (!response.ok) { throw new Error(`Failed to fetch ${url}`); } return response.blob(); }) .then((blob) => { // Get the file extension dynamically using the lambda const extensionMatch = getFileExtensionFromUrl(url); const extension = extensionMatch[1]; // No error handling, must have an extension const fileNameWithIndex = `${fileName} - ${index + 1}.${extension}`; zip.file(fileNameWithIndex, blob); }) .catch((error) => { console.error("下载文件失败:", error); }); }); await Promise.all(promises); // Generate and download the ZIP file zip .generateAsync({ type: "blob" }) .then((content) => { GM_download({ url: URL.createObjectURL(content), name: `${fileName}.zip`, saveAs: false, }); }) .catch((error) => { console.error("ZIP生成失败:", error); }); }; const getFileExtensionFromUrl = (url) => url.match(/\.([a-zA-Z0-9]+)$/); const downloadFile = async (url, index, fileName) => { try { const response = await fetch(url); if (!response.ok) { throw new Error(`Failed to fetch ${url}`); } const blob = await response.blob(); const extensionMatch = getFileExtensionFromUrl(url); const extension = extensionMatch[1]; // No error handling, must have an extension const fileDownloadName = `${fileName} - ${index + 1}.${extension}`; // Use GM_download to download the file GM_download({ url: URL.createObjectURL(blob), name: fileDownloadName, saveAs: false, }); } catch (error) { console.error("下载文件失败:", error); } }; const handleEvent = (event, targetElement) => { event.preventDefault(); event.stopPropagation(); // 阻止事件冒泡 event.stopImmediatePropagation(); // 更强力阻止 if (event.type === "contextmenu") { // 右键事件 const match = targetElement.href.match(/\/(\d+)\??/); if (match && match[1]) { const dynamicId = match[1]; fetchJsonData(dynamicId); } else { console.warn("未匹配到动态ID:", targetElement.href); } } }; const observer = new MutationObserver(() => { let targetElements = document.querySelectorAll( "div.opus-body > div > div > div > div > div > div a" ); targetElements = targetElements.length ? targetElements : document.querySelectorAll( "#page-article .main-content .article-card a" ); targetElements.forEach((targetElement) => { if (!targetElement.hasAttribute("data-listener")) { targetElement.addEventListener( "contextmenu", (event) => handleEvent(event, targetElement), true ); // 捕获阶段绑定 targetElement.setAttribute("data-listener", "true"); // 防止重复绑定 } }); }); // 配置 MutationObserver observer.observe(document.body, { childList: true, subtree: true, }); // 初次匹配页面上已经存在的元素 let initialTargetElements = document.querySelectorAll( "div.opus-body > div > div > div > div > div > div a" ); initialTargetElements = initialTargetElements.length ? initialTargetElements : document.querySelectorAll("#page-article .main-content .article-card a"); initialTargetElements.forEach((targetElement) => { targetElement.addEventListener( "contextmenu", (event) => handleEvent(event, targetElement), true ); // 捕获阶段绑定 }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址