// ==UserScript== // @name 批量图片提取与下载 // @namespace http://tampermonkey.net/ // @version 1.4.0 // @description 提取图片后支持全选、取消全选、一键下载全部图片和下载选中图片为 ZIP 文件。 // @author vicwang // @match *://*/* // @grant none // @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js // @license MIT // @downloadURL none // ==/UserScript== (function () { 'use strict'; // 创建“开始”按钮 const startButton = document.createElement('button'); startButton.textContent = '开始'; startButton.style.position = 'fixed'; startButton.style.top = '10px'; startButton.style.right = '10px'; startButton.style.zIndex = '9999'; startButton.style.padding = '10px 20px'; startButton.style.backgroundColor = '#007BFF'; startButton.style.color = '#fff'; startButton.style.border = 'none'; startButton.style.borderRadius = '5px'; startButton.style.cursor = 'pointer'; startButton.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.2)'; startButton.style.fontSize = '16px'; document.body.appendChild(startButton); // 点击“开始”按钮 startButton.addEventListener('click', () => { const input = prompt('请输入链接(每行一个):'); if (!input) return; const links = input.split('\n').map(link => link.trim()).filter(link => link); if (links.length === 0) { alert('请输入至少一个有效链接'); return; } // 创建图片展示容器 const container = document.createElement('div'); container.style.position = 'fixed'; container.style.top = '0'; container.style.left = '0'; container.style.width = '100%'; container.style.height = '100%'; container.style.backgroundColor = 'rgba(0, 0, 0, 0.9)'; container.style.overflowY = 'scroll'; container.style.zIndex = '10000'; container.style.display = 'flex'; container.style.flexWrap = 'wrap'; container.style.gap = '10px'; container.style.padding = '20px'; document.body.appendChild(container); // 创建关闭按钮 const closeButton = document.createElement('button'); closeButton.textContent = '关闭'; closeButton.style.position = 'fixed'; closeButton.style.top = '10px'; closeButton.style.right = '10px'; closeButton.style.zIndex = '10001'; closeButton.style.padding = '10px 20px'; closeButton.style.backgroundColor = '#FF4C4C'; closeButton.style.color = '#fff'; closeButton.style.border = 'none'; closeButton.style.borderRadius = '5px'; closeButton.style.cursor = 'pointer'; container.appendChild(closeButton); closeButton.addEventListener('click', () => { container.remove(); }); // 图片列表 const imageList = []; const selectedImages = new Set(); // 记录选中的图片 // 检查链接是否为图片 const isImageLink = (url) => { return /\.(jpg|jpeg|png|gif|bmp|webp|svg)$/i.test(url); }; // 提取每个链接中的图片 const promises = links.map(link => { if (isImageLink(link)) { imageList.push(link); return Promise.resolve(); } else { return fetch(link) .then(response => response.text()) .then(html => { const tempDiv = document.createElement('div'); tempDiv.innerHTML = html; const images = Array.from(tempDiv.querySelectorAll('img')).map(img => img.src); imageList.push(...images); }) .catch(() => console.error(`无法加载链接:${link}`)); } }); // 等待所有提取完成 Promise.all(promises).then(() => { if (imageList.length === 0) { alert('未找到任何图片'); return; } // 显示所有图片 const imageElements = []; imageList.forEach((src, index) => { const imgWrapper = document.createElement('div'); imgWrapper.style.flex = '1 1 calc(25% - 10px)'; imgWrapper.style.display = 'flex'; imgWrapper.style.alignItems = 'center'; imgWrapper.style.justifyContent = 'center'; imgWrapper.style.backgroundColor = '#fff'; imgWrapper.style.borderRadius = '5px'; imgWrapper.style.overflow = 'hidden'; imgWrapper.style.position = 'relative'; imgWrapper.style.cursor = 'pointer'; const img = document.createElement('img'); img.src = src; img.style.width = '100%'; img.style.height = 'auto'; img.alt = '图片'; // 选中效果 const overlay = document.createElement('div'); overlay.style.position = 'absolute'; overlay.style.top = '0'; overlay.style.left = '0'; overlay.style.width = '100%'; overlay.style.height = '100%'; overlay.style.backgroundColor = 'rgba(0, 255, 0, 0.5)'; overlay.style.display = 'none'; imgWrapper.appendChild(overlay); imgWrapper.appendChild(img); container.appendChild(imgWrapper); imageElements.push({ src, wrapper: imgWrapper, overlay }); // 点击图片进行选中/取消 imgWrapper.addEventListener('click', () => { if (selectedImages.has(src)) { selectedImages.delete(src); overlay.style.display = 'none'; } else { selectedImages.add(src); overlay.style.display = 'block'; } }); }); // 全选按钮 const selectAllButton = document.createElement('button'); selectAllButton.textContent = '全选'; selectAllButton.style.position = 'fixed'; selectAllButton.style.bottom = '70px'; selectAllButton.style.right = '10px'; selectAllButton.style.zIndex = '10001'; selectAllButton.style.padding = '10px 20px'; selectAllButton.style.backgroundColor = '#007BFF'; selectAllButton.style.color = '#fff'; selectAllButton.style.border = 'none'; selectAllButton.style.borderRadius = '5px'; selectAllButton.style.cursor = 'pointer'; container.appendChild(selectAllButton); selectAllButton.addEventListener('click', () => { imageElements.forEach(({ src, overlay }) => { selectedImages.add(src); overlay.style.display = 'block'; }); }); // 取消全选按钮 const deselectAllButton = document.createElement('button'); deselectAllButton.textContent = '取消全选'; deselectAllButton.style.position = 'fixed'; deselectAllButton.style.bottom = '40px'; deselectAllButton.style.right = '10px'; deselectAllButton.style.zIndex = '10001'; deselectAllButton.style.padding = '10px 20px'; deselectAllButton.style.backgroundColor = '#FF5722'; deselectAllButton.style.color = '#fff'; deselectAllButton.style.border = 'none'; deselectAllButton.style.borderRadius = '5px'; deselectAllButton.style.cursor = 'pointer'; container.appendChild(deselectAllButton); deselectAllButton.addEventListener('click', () => { imageElements.forEach(({ src, overlay }) => { selectedImages.delete(src); overlay.style.display = 'none'; }); }); // 下载选中图片按钮 const downloadSelectedButton = document.createElement('button'); downloadSelectedButton.textContent = '下载选中图片(ZIP)'; downloadSelectedButton.style.position = 'fixed'; downloadSelectedButton.style.bottom = '10px'; downloadSelectedButton.style.right = '10px'; downloadSelectedButton.style.zIndex = '10001'; downloadSelectedButton.style.padding = '10px 20px'; downloadSelectedButton.style.backgroundColor = '#28A745'; downloadSelectedButton.style.color = '#fff'; downloadSelectedButton.style.border = 'none'; downloadSelectedButton.style.borderRadius = '5px'; downloadSelectedButton.style.cursor = 'pointer'; container.appendChild(downloadSelectedButton); downloadSelectedButton.addEventListener('click', async () => { if (selectedImages.size === 0) { alert('请先选择图片!'); return; } const zip = new JSZip(); const selectedArray = Array.from(selectedImages); for (let i = 0; i < selectedArray.length; i++) { const src = selectedArray[i]; const filename = `image_${i + 1}.${src.split('.').pop().split('?')[0]}`; const response = await fetch(src); const blob = await response.blob(); zip.file(filename, blob); } const content = await zip.generateAsync({ type: 'blob' }); const link = document.createElement('a'); link.href = URL.createObjectURL(content); link.download = 'selected_images.zip'; link.click(); }); }); }); })();