Greasy Fork

来自缓存

Greasy Fork is available in English.

COS全站图片下载器

支持cosjiang.com全站的无损图片下载

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         COS全站图片下载器
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  支持cosjiang.com全站的无损图片下载
// @author       YourName
// @match        https://www.cosjiang.com/*
// @grant        GM_download
// @grant        GM_notification
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @connect      www.cosjiang.com
// ==/UserScript==

(function() {
    'use strict';

    // 配置中心(用户可自定义部分)
    const CONFIG = {
        THUMB_TO_ORIGINAL: [     // 缩略图转原图路径规则
            ['/thumbs/', '/full/'],
            ['/small/', '/large/'],
            [/\d{3}x\d{3}/, '2000x2000'], // 替换尺寸参数
            [/(\.[a-z]+)\?.*/i, '$1']     // 清除URL参数
        ],
        TITLE_SELECTORS: [       // 标题抓取优先级
            'h1.album-title',
            'h1.post-title',
            'h1.title',
            'title'
        ]
    };

    let isProcessing = false;

    // 创建智能下载按钮
    function createSmartButton() {
        const btn = document.createElement('button');
        btn.textContent = '🏞 下载原图';
        btn.style = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 99999;
            padding: 12px 24px;
            background: linear-gradient(135deg, #2196F3, #4CAF50);
            color: white;
            border: none;
            border-radius: 25px;
            cursor: pointer;
            box-shadow: 0 4px 15px rgba(0,0,0,0.2);
            font-family: 'Microsoft YaHei', sans-serif;
            transition: transform 0.2s;
        `;
        btn.addEventListener('mouseover', () => btn.style.transform = 'scale(1.05)');
        btn.addEventListener('mouseout', () => btn.style.transform = 'none');

        document.body.appendChild(btn);
        return btn;
    }

    // 核心处理器
    async function processDownload() {
        if (isProcessing) return;
        isProcessing = true;

        try {
            // 自动滚动加载
            await autoScroll();

            // 获取页面信息
            const pageInfo = {
                title: getPageTitle(),
                url: window.location.href,
                timestamp: new Date().toISOString().slice(0, 10)
            };

            // 提取并处理图片
            const images = Array.from(document.images)
                .map(img => ({
                    src: processImageURL(img.src),
                    alt: img.alt || pageInfo.title
                }))
                .filter(img => /\.(jpe?g|png|webp)(\?|$)/i.test(img.src));

            if (images.length === 0) {
                GM_notification({ title: '⚠️ 未找到图片', text: '请检查页面结构' });
                return;
            }

            // 批量下载
            GM_notification({
                title: '🎉 开始下载',
                text: `找到 ${images.length} 张图片`,
                timeout: 2000
            });

            images.forEach((img, index) => {
                setTimeout(() => {
                    const filename = generateFilename(img, index, pageInfo);
                    GM_download({
                        url: img.src,
                        name: filename,
                        headers: {
                            Referer: pageInfo.url,
                            'User-Agent': navigator.userAgent
                        }
                    });
                }, index * 500); // 防止请求过载
            });

        } catch (error) {
            GM_notification({ title: '❌ 下载失败', text: error.message });
        } finally {
            isProcessing = false;
        }
    }

    // 智能URL处理
    function processImageURL(url) {
        if (!url.includes('://')) url = new URL(url, window.location.href).href;

        // 应用替换规则
        CONFIG.THUMB_TO_ORIGINAL.forEach(rule => {
            if (Array.isArray(rule)) {
                url = url.replace(rule[0], rule[1]);
            }
        });

        return url;
    }

    // 高级标题获取
    function getPageTitle() {
        let title = '';
        for (const selector of CONFIG.TITLE_SELECTORS) {
            const el = document.querySelector(selector);
            if (el && el.textContent.trim()) {
                title = el.textContent;
                break;
            }
        }

        return title
            .replace(/[\x00-\x1F\x7F\\/:"*?<>|]/g, '_') // 过滤非法字符
            .replace(/_+/g, '_')
            .trim()
            .substring(0, 50) || 'COS_Image';
    }

    // 生成规范文件名
    function generateFilename(img, index, pageInfo) {
        const ext = (img.src.match(/\.([a-z0-9]+)(\?|$)/i) || ['','jpg'])[1];
        return `${pageInfo.title}_${(index + 1).toString().padStart(3, '0')}.${ext}`;
    }

    // 自动滚动加载(增强版)
    async function autoScroll() {
        return new Promise(resolve => {
            let lastHeight = 0;
            let retryCount = 0;

            const scrollInterval = setInterval(() => {
                window.scrollTo(0, document.body.scrollHeight);
                const newHeight = document.body.scrollHeight;

                if (newHeight > lastHeight) {
                    lastHeight = newHeight;
                    retryCount = 0;
                } else if (++retryCount > 5) {
                    clearInterval(scrollInterval);
                    resolve();
                }
            }, 1500);
        });
    }

    // 初始化
    const btn = createSmartButton();
    btn.addEventListener('click', processDownload);

    // 注册右键菜单命令
    GM_registerMenuCommand('⚙️ 配置下载规则', () => {
        const configWindow = window.open('', '_blank',
            'width=600,height=400,menubar=no,toolbar=no');
        configWindow.document.write(`
            <h2>下载配置</h2>
            <div style="padding:20px">
                <p>当前路径替换规则:</p >
                <pre>${JSON.stringify(CONFIG.THUMB_TO_ORIGINAL, null, 2)}</pre>
                <button onclick="window.close()">关闭</button>
            </div>
        `);
    });
})();