// ==UserScript== // @name 批量保存Telegram用户头像 // @namespace http://tampermonkey.net/ // @version 1.1 // @description 提取blob URL 中的 UUID 作为文件名批量下载头像,默认保存格式为jpg // @author GR:PM // @license MIT // @match https://web.telegram.org/k/* // @grant none // @downloadURL https://update.greasyfork.icu/scripts/571249/%E6%89%B9%E9%87%8F%E4%BF%9D%E5%AD%98Telegram%E7%94%A8%E6%88%B7%E5%A4%B4%E5%83%8F.user.js // @updateURL https://update.greasyfork.icu/scripts/571249/%E6%89%B9%E9%87%8F%E4%BF%9D%E5%AD%98Telegram%E7%94%A8%E6%88%B7%E5%A4%B4%E5%83%8F.meta.js // ==/UserScript== (function () { "use strict"; // 创建控制按钮 function createUI() { const container = document.createElement("div"); container.style.cssText = "position:fixed; bottom:20px; right:20px; z-index:9999; display:flex; flex-direction:column; gap:10px;"; const autoBtn = document.createElement("button"); autoBtn.innerText = "⚡ 自动加载并下载全部头像"; styleButton(autoBtn, "#ff8c00"); autoBtn.onclick = startAutoProcess; container.appendChild(autoBtn); document.body.appendChild(container); } function styleButton(btn, color) { btn.style.cssText = ` padding: 12px 20px; background-color: ${color}; color: white; border: none; border-radius: 8px; cursor: pointer; box-shadow: 0 4px 12px rgba(0,0,0,0.2); font-weight: bold; transition: transform 0.2s; `; btn.onmouseover = () => (btn.style.transform = "scale(1.05)"); btn.onmouseout = () => (btn.style.transform = "scale(1)"); } // 等待函数 const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // 核心流程:自动翻页 -> 等待加载 -> 下载 async function startAutoProcess() { console.log("开始自动执行..."); let nextButton = document.querySelector(".profile-avatars-arrow-next"); // 1. 循环点击“下一步”直到按钮消失或不可点击 while ( nextButton && getComputedStyle(nextButton).display !== "none" && getComputedStyle(nextButton).visibility !== "hidden" ) { nextButton.click(); // 稍微等待动画和加载,300ms 是一个比较稳妥的值 await sleep(300); // 重新获取按钮状态 nextButton = document.querySelector(".profile-avatars-arrow-next"); // 检查是否还有未加载的 hide 元素 const hiddenAvatars = document.querySelectorAll( ".profile-avatars-avatar.hide", ); if (hiddenAvatars.length === 0) break; } console.log("翻页完成,等待最终资源同步..."); await sleep(1000); // 给 Blob 生成留一点最后的时间 // 2. 执行下载 downloadAll(); } function downloadAll() { const avatarImages = document.querySelectorAll( ".profile-avatars-avatars .avatar-photo", ); if (avatarImages.length === 0) { alert("未找到可下载的头像图片。"); return; } console.log(`准备下载 ${avatarImages.length} 张头像...`); avatarImages.forEach((img, index) => { const src = img.src; if (!src || !src.startsWith("blob:")) return; const uuid = src.split("/").pop(); const fileName = `${uuid}.jpg`; const link = document.createElement("a"); link.href = src; link.download = fileName; // 批量下载间隔,防止浏览器崩溃 setTimeout(() => { document.body.appendChild(link); link.click(); document.body.removeChild(link); console.log( `[${index + 1}/${avatarImages.length}] 已保存: ${fileName}`, ); }, index * 200); }); console.log(`完成。`) } createUI(); })();