您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
微博内容页增加图片下载的按钮
// ==UserScript== // @name 微博图片下载器 // @namespace https://1mether.me/ // @version 0.1 // @description 微博内容页增加图片下载的按钮 // @author 乙醚(@locoda) // @match http*://*.weibo.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=weibo.com // @license MIT // ==/UserScript== (function () { "use strict"; // ============== // = Main = // ============== var observer = new MutationObserver(function (mutations, observer) { // console.log(mutations); processWeiboTimeline(); }); observer.observe(document, { subtree: true, childList: true, }); // ================================ // = Button Injection Utils = // ================================ function processWeiboTimeline() { var divs = Array.from(document.querySelectorAll("article")); divs.forEach((div) => { if ( div.querySelector("div[class^=picture]") && !div.querySelector(".download-button") ) { injectImageDownloadButton(div); } }); } function injectImageDownloadButton(element) { // 图片下载按钮 const like = Array.from( element.querySelectorAll(".woo-box-item-flex") ).pop(); var download = like.cloneNode(true); download.classList.add("download-button"); var btn = download.querySelector("button"); btn.removeChild(btn.firstChild); btn.firstChild.textContent = "下载"; btn.firstChild.classList.remove("woo-like-liked"); btn.addEventListener("click", function () { getInfoAndDownloadImages(element); }); like.parentElement.appendChild(download); } function getInfoAndDownloadImages(element) { // 获取图片链接 const id = element .querySelector("a[class^=head-info_time]") .href.split("/") .pop() .split("?")[0]; fetch("https://weibo.com/ajax/statuses/show?id=" + id) .then((response) => response.json()) .then((response) => { console.log(response); const prefix = response.user.screen_name + "_" + id + "_"; var imgs = []; if (response.hasOwnProperty("retweeted_status")) { response = response.retweeted_status; } for (var pic in response.pic_infos) { imgs.push(response.pic_infos[pic].largest.url); } downloadImages(imgs, prefix); }); } // ======================== // = Download Utils = // ======================== function downloadImages(imgs, prefix = "") { console.debug("正在下载图片: " + imgs); // Thanks to https://github.com/y252328/Instagram_Download_Button if (imgs.length <= 10) { // 同时最多下载十张图 imgs.forEach((img, index) => downloadOneImage(img, appendIndexToPrefix(prefix, index)) ); } else { // 设置延时下载更多图片 https://stackoverflow.com/questions/56244902/56245610#56245610 imgs.forEach((img, index) => { setTimeout(function () { downloadOneImage(img, appendIndexToPrefix(prefix, index)); }, index * 200); }); } } function appendIndexToPrefix(prefix, index) { return ( prefix + (index + 1).toLocaleString("en-US", { minimumIntegerDigits: 3, useGrouping: false, }) + "_" ); } function downloadOneImage(img, prefix = "") { fetch(img, { headers: new Headers({ Origin: window.location.origin, }), mode: "cors", cache: "no-cache", }) .then((response) => response.blob()) .then((blob) => dowloadBlob( window.URL.createObjectURL(blob), prefix + img.substring(img.lastIndexOf("/") + 1) ) ) .catch((e) => console.error(e)); } function dowloadBlob(blob, filename) { var a = document.createElement("a"); a.download = sanitizeFileName(filename); a.href = blob; document.body.appendChild(a); a.click(); a.remove(); } // ====================== // = Naming Utils = // ====================== function sanitizeFileName(input, replacement = "_") { // Thanks to https://github.com/parshap/node-sanitize-filename/blob/master/index.js const illegalRe = /[\/\?<>\\:\*\|"]/g; const controlRe = /[\x00-\x1f\x80-\x9f]/g; const reservedRe = /^\.+$/; const windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i; const windowsTrailingRe = /[\. ]+$/; return input .split(/\s/g) .filter((s) => s) .join("_") .replace(illegalRe, replacement) .replace(controlRe, replacement) .replace(reservedRe, replacement) .replace(windowsReservedRe, replacement) .replace(windowsTrailingRe, replacement); } })();