您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds ZIP download buttons on AO3 works pages and auto-downloads each with delay and pagination
// ==UserScript== // @name AO3 ZIP Auto Downloader Simple // @namespace https://archiveofourown.org/ // @version 1.0.0 // @description Adds ZIP download buttons on AO3 works pages and auto-downloads each with delay and pagination // @author ChatGPT // @license MIT // @match https://archiveofourown.org/works* // @grant none // @run-at document-end // ==/UserScript== (async function() { 'use strict'; const delayMs = 4000; let isRunning = false; let isPaused = false; let downloadButtons = []; // Wait helper function wait(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // Extract work ID from AO3 URL parts function extractWorkId(href) { const parts = href.split('/'); const worksIndex = parts.indexOf('works'); if (worksIndex !== -1 && parts.length > worksIndex + 1) { return parts[worksIndex + 1]; } return null; } // Add ZIP buttons next to each work title function addZipButtons() { const blurbs = document.querySelectorAll('li.blurb'); const buttons = []; blurbs.forEach(blurb => { const titleLink = blurb.querySelector('.header.module .heading a'); if (!titleLink) return; const workId = extractWorkId(titleLink.href); if (!workId) return; const title = titleLink.textContent.trim().replace(/[^\w\s\-]/g, ''); const zipUrl = `/downloads/${workId}/${encodeURIComponent(title)}.zip?updated_at=${Date.now()}`; // Avoid duplicate buttons if (blurb.querySelector('.ao3-zip-btn')) return; const btn = document.createElement('a'); btn.href = zipUrl; btn.textContent = 'ZIP ↓'; btn.className = 'ao3-zip-btn'; btn.style.cssText = ` background-color: #c00; color: white; padding: 3px 7px; margin-left: 10px; border-radius: 5px; font-size: 12px; text-decoration: none; cursor: pointer; `; blurb.querySelector('.header.module .heading').appendChild(btn); buttons.push(btn); }); return buttons; } // Create floating control panel function createControlPanel() { if (document.getElementById('ao3-zip-control-panel')) return; const panel = document.createElement('div'); panel.id = 'ao3-zip-control-panel'; panel.style = ` position: fixed; top: 10px; left: 10px; background: #fff; border: 1px solid #444; padding: 10px; border-radius: 6px; z-index: 999999; font-family: Arial, sans-serif; font-size: 14px; `; panel.innerHTML = ` <b>AO3 ZIP Downloader</b><br><br> <button id="ao3-start-btn">▶ Start</button> <button id="ao3-pause-btn">⏸ Pause</button> <button id="ao3-reset-btn">🔁 Reset</button> <p id="ao3-status" style="margin-top:8px;">Status: Idle</p> `; document.body.appendChild(panel); document.getElementById('ao3-start-btn').onclick = startDownloads; document.getElementById('ao3-pause-btn').onclick = () => { isPaused = !isPaused; document.getElementById('ao3-pause-btn').textContent = isPaused ? '▶ Resume' : '⏸ Pause'; updateStatus(); }; document.getElementById('ao3-reset-btn').onclick = () => { location.reload(); }; } // Update status text function updateStatus(text) { const status = document.getElementById('ao3-status'); if (!status) return; status.textContent = `Status: ${text}`; } // Main auto-download function async function startDownloads() { if (isRunning) return; isRunning = true; downloadButtons = addZipButtons(); if (downloadButtons.length === 0) { updateStatus('No works found on this page.'); isRunning = false; return; } updateStatus('Starting downloads...'); for (let i = 0; i < downloadButtons.length; i++) { while (isPaused) { updateStatus('Paused'); await wait(500); } updateStatus(`Downloading work ${i + 1} of ${downloadButtons.length}...`); downloadButtons[i].click(); await wait(delayMs); } // After finishing page, try next page const nextPageLink = document.querySelector('ol.pagination li.next a'); if (nextPageLink) { updateStatus('Going to next page...'); await wait(1000); window.location.href = nextPageLink.href; } else { updateStatus('All downloads complete.'); alert('✅ All downloads complete!'); isRunning = false; } } // Wait for page to load blurbs function waitForBlurbs() { return new Promise(resolve => { const interval = setInterval(() => { if (document.querySelector('li.blurb')) { clearInterval(interval); resolve(); } }, 300); }); } // Initialize await waitForBlurbs(); createControlPanel(); updateStatus('Idle'); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址