🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

Greasy Fork is available in English.

📂 缓存分发状态(共享加速已生效)
🕒 页面同步时间:2026/02/04 16:48:12
🔄 下次更新时间:2026/02/04 17:48:12
手动刷新缓存

Scribd Downloader

📚 Download documents from Scribd for free as PDF - Fully automated!

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

You will need to install an extension such as Tampermonkey to install this script.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği indirebilmeniz için ayrıca Tampermonkey gibi bir eklenti kurmanız gerekmektedir.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Zateb bir user-style yöneticim var, yükleyeyim!)

🚀 安装遇到问题?关注公众号获取帮助

公众号二维码

扫码关注【爱吃馍】

回复【脚本】获取最新教程和防失联地址

// ==UserScript==
// @name         Scribd Downloader
// @namespace    https://github.com/ThanhNguyxn/scribd-downloader
// @version      2.3.2
// @description  📚 Download documents from Scribd for free as PDF - Fully automated!
// @author       ThanhNguyxn
// @match        https://www.scribd.com/*
// @icon         https://www.scribd.com/favicon.ico
// @grant        GM_addStyle
// @grant        GM_setClipboard
// @grant        GM_openInTab
// @run-at       document-idle
// @license      MIT
// @homepageURL  https://github.com/ThanhNguyxn/scribd-downloader
// @supportURL   https://github.com/ThanhNguyxn/scribd-downloader/issues
// ==/UserScript==

(function () {
    'use strict';

    const BUTTON_DELAY = 1500;
    const GITHUB_URL = 'https://github.com/ThanhNguyxn/scribd-downloader';
    const SPONSOR_URL = 'https://github.com/sponsors/ThanhNguyxn';
    const DONATE_URL = 'https://buymeacoffee.com/thanhnguyxn';

    const styles = `
        #sd-floating-btn {
            position: fixed !important;
            top: 80px !important;
            right: 20px !important;
            z-index: 2147483647 !important;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
            color: white !important;
            border: none !important;
            padding: 12px 20px !important;
            border-radius: 12px !important;
            font-size: 14px !important;
            font-weight: 700 !important;
            cursor: pointer !important;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.5) !important;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
            display: flex !important;
            align-items: center !important;
            gap: 8px !important;
            transition: all 0.3s ease !important;
            text-decoration: none !important;
        }

        #sd-floating-btn:hover {
            transform: scale(1.05) !important;
            box-shadow: 0 6px 25px rgba(102, 126, 234, 0.6) !important;
        }

        #sd-floating-btn:active {
            transform: scale(0.98) !important;
        }

        #sd-floating-btn.loading {
            background: linear-gradient(135deg, #ffa726 0%, #fb8c00 100%) !important;
            pointer-events: none !important;
        }

        #sd-popup {
            position: fixed !important;
            top: 0 !important;
            left: 0 !important;
            width: 100% !important;
            height: 100% !important;
            background: rgba(0,0,0,0.85) !important;
            z-index: 2147483647 !important;
            display: flex !important;
            justify-content: center !important;
            align-items: center !important;
            opacity: 0;
            visibility: hidden;
            transition: all 0.3s ease !important;
        }

        #sd-popup.show {
            opacity: 1 !important;
            visibility: visible !important;
        }

        #sd-popup-content {
            background: white !important;
            padding: 30px !important;
            border-radius: 20px !important;
            max-width: 420px !important;
            width: 90% !important;
            text-align: center !important;
            box-shadow: 0 25px 80px rgba(0,0,0,0.4) !important;
            transform: scale(0.9);
            transition: transform 0.3s ease !important;
        }

        #sd-popup.show #sd-popup-content {
            transform: scale(1) !important;
        }

        #sd-popup h2 {
            margin: 0 0 20px 0 !important;
            color: #333 !important;
            font-size: 22px !important;
            font-weight: 700 !important;
        }

        #sd-url-display {
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%) !important;
            color: #00d9ff !important;
            padding: 15px !important;
            border-radius: 10px !important;
            font-family: 'Monaco', 'Consolas', monospace !important;
            font-size: 12px !important;
            word-break: break-all !important;
            margin: 15px 0 !important;
            text-align: left !important;
            border: 2px solid #667eea !important;
            user-select: all !important;
            cursor: text !important;
        }

        .sd-btn {
            padding: 12px 24px !important;
            border: none !important;
            border-radius: 10px !important;
            font-size: 14px !important;
            font-weight: 600 !important;
            cursor: pointer !important;
            transition: all 0.2s ease !important;
            margin: 5px !important;
            text-decoration: none !important;
            display: inline-flex !important;
            align-items: center !important;
            gap: 6px !important;
        }

        .sd-btn-primary {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
            color: white !important;
        }

        .sd-btn-success {
            background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%) !important;
            color: white !important;
        }

        .sd-btn-warning {
            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%) !important;
            color: white !important;
        }

        .sd-btn-close {
            background: #e0e0e0 !important;
            color: #333 !important;
        }

        .sd-btn:hover {
            transform: scale(1.05) !important;
            box-shadow: 0 5px 20px rgba(0,0,0,0.2) !important;
        }

        .sd-info {
            background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%) !important;
            border-left: 4px solid #4caf50 !important;
            padding: 12px 15px !important;
            margin: 15px 0 !important;
            border-radius: 0 10px 10px 0 !important;
            text-align: left !important;
            font-size: 13px !important;
            color: #2e7d32 !important;
        }

        .sd-btn-group {
            display: flex !important;
            gap: 8px !important;
            justify-content: center !important;
            flex-wrap: wrap !important;
            margin-top: 15px !important;
        }

        .sd-links {
            margin-top: 20px !important;
            padding-top: 15px !important;
            border-top: 1px solid #eee !important;
            display: flex !important;
            justify-content: center !important;
            gap: 15px !important;
        }

        .sd-link {
            color: #666 !important;
            text-decoration: none !important;
            font-size: 12px !important;
            display: flex !important;
            align-items: center !important;
            gap: 5px !important;
            transition: color 0.2s !important;
        }

        .sd-link:hover {
            color: #667eea !important;
        }

        #sd-download-btn {
            position: fixed !important;
            top: 20px !important;
            right: 20px !important;
            z-index: 2147483647 !important;
            background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%) !important;
            color: white !important;
            border: none !important;
            padding: 14px 24px !important;
            border-radius: 12px !important;
            font-size: 15px !important;
            font-weight: 700 !important;
            cursor: pointer !important;
            box-shadow: 0 4px 15px rgba(17, 153, 142, 0.5) !important;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
            display: flex !important;
            align-items: center !important;
            gap: 8px !important;
            transition: all 0.3s ease !important;
        }

        #sd-download-btn:hover {
            transform: scale(1.05) !important;
            box-shadow: 0 6px 25px rgba(17, 153, 142, 0.6) !important;
        }

        #sd-download-btn.loading {
            background: linear-gradient(135deg, #ffa726 0%, #fb8c00 100%) !important;
        }

        #sd-progress-popup {
            position: fixed !important;
            top: 0 !important;
            left: 0 !important;
            width: 100% !important;
            height: 100% !important;
            background: rgba(0,0,0,0.9) !important;
            z-index: 2147483647 !important;
            display: flex !important;
            justify-content: center !important;
            align-items: center !important;
        }

        #sd-progress-content {
            background: white !important;
            padding: 35px !important;
            border-radius: 20px !important;
            text-align: center !important;
            min-width: 320px !important;
        }

        #sd-progress-bar {
            width: 100% !important;
            height: 10px !important;
            background: #e0e0e0 !important;
            border-radius: 10px !important;
            overflow: hidden !important;
            margin: 20px 0 !important;
        }

        #sd-progress-fill {
            height: 100% !important;
            background: linear-gradient(90deg, #667eea, #764ba2) !important;
            width: 0% !important;
            transition: width 0.3s ease !important;
            border-radius: 10px !important;
        }

        #sd-progress-text {
            color: #666 !important;
            font-size: 15px !important;
            margin-bottom: 10px !important;
        }
    `;

    const styleEl = document.createElement('style');
    styleEl.textContent = styles;
    document.head.appendChild(styleEl);

    function getDocId() {
        const url = window.location.href;
        const match = url.match(/(?:document|doc|embeds|read|presentation)\/(\d+)/);
        return match ? match[1] : null;
    }

    function isEmbed() {
        return window.location.href.includes('/embeds/');
    }

    function getEmbedUrl(id) {
        return `https://www.scribd.com/embeds/${id}/content`;
    }

    function copyText(text) {
        try {
            if (typeof GM_setClipboard === 'function') {
                GM_setClipboard(text, 'text');
                return true;
            }
        } catch (e) { }

        try {
            navigator.clipboard.writeText(text);
            return true;
        } catch (e) { }

        try {
            const ta = document.createElement('textarea');
            ta.value = text;
            ta.style.cssText = 'position:fixed;top:-9999px;left:-9999px';
            document.body.appendChild(ta);
            ta.select();
            document.execCommand('copy');
            ta.remove();
            return true;
        } catch (e) { }

        return false;
    }

    function sleep(ms) {
        return new Promise(r => setTimeout(r, ms));
    }

    function showMainButton() {
        if (document.getElementById('sd-floating-btn')) return;

        const docId = getDocId();
        if (!docId) return;

        const btn = document.createElement('button');
        btn.id = 'sd-floating-btn';
        btn.innerHTML = '📥 Download PDF';
        btn.onclick = startAutoDownload;
        document.body.appendChild(btn);
    }

    async function startAutoDownload() {
        const btn = document.getElementById('sd-floating-btn');
        const docId = getDocId();

        if (!docId) {
            alert('Cannot find document ID!');
            return;
        }

        const embedUrl = getEmbedUrl(docId);

        btn.classList.add('loading');
        btn.innerHTML = '⏳ Opening...';

        showAutoPopup(embedUrl);
    }

    function showAutoPopup(embedUrl) {
        const existing = document.getElementById('sd-popup');
        if (existing) existing.remove();

        const popup = document.createElement('div');
        popup.id = 'sd-popup';
        popup.innerHTML = `
            <div id="sd-popup-content">
                <h2>📚 Scribd Downloader</h2>
                
                <div class="sd-info">
                    ✨ <strong>Auto mode:</strong> Opening embed page in new tab...
                </div>

                <div id="sd-url-display">${embedUrl}</div>

                <p style="color: #666; font-size: 13px; margin: 15px 0;">
                    A new tab will open automatically.<br>
                    Click the <strong style="color: #11998e;">green button</strong> there to download!
                </p>

                <div class="sd-btn-group">
                    <button class="sd-btn sd-btn-success" id="sd-open-now">🚀 Open Now</button>
                    <button class="sd-btn sd-btn-warning" id="sd-open-incognito">🕵️ Manual (Incognito)</button>
                    <button class="sd-btn sd-btn-close" id="sd-close-btn">Close</button>
                </div>

                <div class="sd-links">
                    <a href="${GITHUB_URL}" target="_blank" class="sd-link">⭐ GitHub</a>
                    <a href="${SPONSOR_URL}" target="_blank" class="sd-link">💖 Sponsor</a>
                    <a href="${DONATE_URL}" target="_blank" class="sd-link">☕ Buy me a coffee</a>
                </div>
            </div>
        `;

        document.body.appendChild(popup);

        requestAnimationFrame(() => {
            popup.classList.add('show');
        });

        const autoTimer = setTimeout(() => {
            openEmbedPage(embedUrl);
        }, 1500);

        document.getElementById('sd-open-now').onclick = function () {
            clearTimeout(autoTimer);
            openEmbedPage(embedUrl);
        };

        document.getElementById('sd-open-incognito').onclick = function () {
            clearTimeout(autoTimer);
            copyText(embedUrl);
            this.innerHTML = '✅ URL Copied!';
            showManualInstructions();
        };

        document.getElementById('sd-close-btn').onclick = function () {
            clearTimeout(autoTimer);
            closePopup();
        };

        popup.onclick = function (e) {
            if (e.target === popup) {
                clearTimeout(autoTimer);
                closePopup();
            }
        };
    }

    function openEmbedPage(url) {
        if (typeof GM_openInTab === 'function') {
            GM_openInTab(url, { active: false, insert: true, setParent: true });
        } else {
            const newTab = window.open(url, '_blank');
            if (newTab) {
                window.focus();
            }
        }

        const btn = document.getElementById('sd-floating-btn');
        if (btn) {
            btn.classList.remove('loading');
            btn.innerHTML = '✅ Opened!';
            setTimeout(() => {
                btn.innerHTML = '📥 Download PDF';
            }, 3000);
        }

        const popupContent = document.getElementById('sd-popup-content');
        if (popupContent) {
            popupContent.innerHTML = `
                <h2>✅ Tab Opened!</h2>
                
                <div class="sd-info" style="background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%) !important;">
                    🎉 <strong>Success!</strong> A new tab has been opened in the background.
                </div>

                <p style="color: #666; font-size: 13px; margin: 15px 0;">
                    📌 <strong>Next steps:</strong><br>
                    1. Switch to the new tab<br>
                    2. Click the <strong style="color: #11998e;">green Download button</strong><br>
                    3. Wait for all pages to load<br>
                    4. Save as PDF
                </p>

                <div class="sd-btn-group">
                    <button class="sd-btn sd-btn-close" id="sd-close-btn2">Got it!</button>
                </div>

                <div class="sd-links">
                    <a href="${GITHUB_URL}" target="_blank" class="sd-link">⭐ GitHub</a>
                    <a href="${SPONSOR_URL}" target="_blank" class="sd-link">💖 Sponsor</a>
                    <a href="${DONATE_URL}" target="_blank" class="sd-link">☕ Buy me a coffee</a>
                </div>

                <p style="color: #999; font-size: 11px; margin-top: 15px;">
                    Made with ❤️ by <a href="${GITHUB_URL}" target="_blank" style="color: #667eea;">ThanhNguyxn</a>
                </p>
            `;

            const closeBtn2 = document.getElementById('sd-close-btn2');
            if (closeBtn2) {
                closeBtn2.onclick = closePopup;
            }
        }
    }

    function showManualInstructions() {
        const content = document.getElementById('sd-popup-content');
        if (!content) return;

        content.innerHTML = `
            <h2>🕵️ Manual Mode</h2>
            
            <div class="sd-info">
                ✅ <strong>URL copied!</strong> Follow these steps:
            </div>

            <ol style="text-align: left; color: #444; line-height: 1.8; padding-left: 20px; margin: 20px 0;">
                <li>Press <strong>Ctrl+Shift+N</strong> (Incognito window)</li>
                <li>Paste the URL (<strong>Ctrl+V</strong>)</li>
                <li>Press <strong>Enter</strong></li>
                <li>Click the <strong style="color: #11998e;">green Download button</strong></li>
            </ol>

            <div class="sd-btn-group">
                <button class="sd-btn sd-btn-close" id="sd-close-btn2">Got it!</button>
            </div>

            <div class="sd-links">
                <a href="${GITHUB_URL}" target="_blank" class="sd-link">⭐ GitHub</a>
                <a href="${SPONSOR_URL}" target="_blank" class="sd-link">💖 Sponsor</a>
                <a href="${DONATE_URL}" target="_blank" class="sd-link">☕ Buy me a coffee</a>
            </div>
        `;

        document.getElementById('sd-close-btn2').onclick = closePopup;
    }

    function closePopup() {
        const popup = document.getElementById('sd-popup');
        const btn = document.getElementById('sd-floating-btn');

        if (popup) {
            popup.classList.remove('show');
            setTimeout(() => popup.remove(), 300);
        }

        if (btn) {
            btn.classList.remove('loading');
            btn.innerHTML = '📥 Download PDF';
        }
    }

    function showEmbedButton() {
        if (document.getElementById('sd-download-btn')) return;

        const btn = document.createElement('button');
        btn.id = 'sd-download-btn';
        btn.innerHTML = '⬇️ Download PDF';
        btn.onclick = startDownload;
        document.body.appendChild(btn);

        if (document.referrer.includes('scribd.com')) {
            setTimeout(() => {
                const autoBtn = document.getElementById('sd-download-btn');
                if (autoBtn && !autoBtn.classList.contains('loading')) {
                    autoBtn.innerHTML = '🚀 Starting...';
                    setTimeout(startDownload, 500);
                }
            }, 2000);
        }
    }

    async function startDownload() {
        const btn = document.getElementById('sd-download-btn');
        btn.classList.add('loading');
        btn.innerHTML = '⏳ Processing...';

        const progress = document.createElement('div');
        progress.id = 'sd-progress-popup';
        progress.innerHTML = `
            <div id="sd-progress-content">
                <h2>📚 Preparing PDF...</h2>
                <div id="sd-progress-text">Loading pages...</div>
                <div id="sd-progress-bar">
                    <div id="sd-progress-fill"></div>
                </div>
                <p style="color: #888; font-size: 12px; margin-top: 15px;">
                    Please wait, this may take a moment...
                </p>
            </div>
        `;
        document.body.appendChild(progress);

        const fill = document.getElementById('sd-progress-fill');
        const text = document.getElementById('sd-progress-text');

        try {
            text.textContent = '📄 Loading all pages...';

            const scrollContainer = document.querySelector('.document_scroller');
            
            const pageContainer = document.querySelector('.outer_page_container') || 
                                  document.querySelector('.autogen_class_views_EmbedDocument') ||
                                  document.body;
            
            const pages = pageContainer.querySelectorAll('.outer_page, .page');
            console.log(`[Scribd Downloader] Found ${pages.length} pages`);

            if (pages.length > 0) {
                for (let i = 0; i < pages.length; i++) {
                    pages[i].scrollIntoView({ behavior: 'instant', block: 'start' });

                    if (scrollContainer) {
                        scrollContainer.scrollTop = pages[i].offsetTop;
                    }

                    await sleep(500);

                    const pct = Math.round(((i + 1) / pages.length) * 50);
                    fill.style.width = pct + '%';
                    text.textContent = `📄 Loading page ${i + 1}/${pages.length}...`;
                }
            } else {
                console.log('[Scribd Downloader] No pages found, using fallback scroll');
                const container = scrollContainer || document.documentElement;
                const totalHeight = container.scrollHeight;
                const viewportHeight = window.innerHeight;
                const steps = Math.ceil(totalHeight / viewportHeight);
                
                for (let i = 0; i <= steps; i++) {
                    const scrollPos = viewportHeight * i;
                    if (scrollContainer) {
                        scrollContainer.scrollTop = scrollPos;
                    }
                    window.scrollTo(0, scrollPos);
                    await sleep(300);
                    fill.style.width = Math.round((i / steps) * 50) + '%';
                }
            }

            console.log('[Scribd Downloader] Finished scrolling');

            fill.style.width = '60%';
            text.textContent = '🧹 Removing UI elements...';
            await sleep(200);

            const cleanupSelectors = [
                '.toolbar_drop',
                '.mobile_overlay',
                '.promo_banner',
                '.auto_scribd_download_banner',
                '.inter_pages_container',
                '.missing_page_buy_link',
                '#global_header',
                '.page_missing_explanation',
                '.toolbar_top',
                '.toolbar_bottom',
                '.promo_div',
                '.ReactModalPortal',
                '.between_page_module',
                '.auto_doc_domain_name',
                '.global_wrapper_header'
            ];

            cleanupSelectors.forEach(selector => {
                try {
                    document.querySelectorAll(selector).forEach(el => el.remove());
                } catch (e) { }
            });

            fill.style.width = '70%';
            text.textContent = '🧹 Fixing layout...';
            await sleep(200);

            const scrollers = document.querySelectorAll('.document_scroller');
            scrollers.forEach(el => {
                el.classList.remove('document_scroller');
                el.style.overflow = 'visible';
                el.style.height = 'auto';
                el.style.maxHeight = 'none';
                el.style.position = 'relative';
            });

            document.body.style.overflow = 'visible';
            document.body.style.height = 'auto';
            document.documentElement.style.overflow = 'visible';

            fill.style.width = '90%';
            text.textContent = '✨ Preparing for print...';
            await sleep(200);

            const printStyles = document.createElement('style');
            printStyles.id = 'sd-print-styles';
            printStyles.textContent = `
                @media print {
                    .toolbar_top, .toolbar_bottom, .toolbar_drop,
                    #sd-download-btn, #sd-progress-popup, #sd-floating-btn {
                        display: none !important;
                    }
                    
                    @page {
                        margin: 0;
                    }
                    
                    .outer_page, .page {
                        page-break-after: always;
                        page-break-inside: avoid;
                    }
                    .outer_page:last-child, .page:last-child {
                        page-break-after: auto;
                    }
                }
            `;
            document.head.appendChild(printStyles);

            window.scrollTo(0, 0);
            if (scrollContainer) {
                scrollContainer.scrollTop = 0;
            }

            fill.style.width = '100%';
            text.textContent = '✅ Ready! Opening print dialog...';
            await sleep(500);

            progress.remove();

            if (btn) {
                btn.remove();
            }

            window.print();

            const newBtn = document.createElement('button');
            newBtn.id = 'sd-download-btn';
            newBtn.innerHTML = '✅ Done! Print again?';
            newBtn.onclick = startDownload;
            document.body.appendChild(newBtn);

            setTimeout(() => {
                const b = document.getElementById('sd-download-btn');
                if (b) b.innerHTML = '⬇️ Download PDF';
            }, 5000);

        } catch (err) {
            console.error('[Scribd Downloader] Download error:', err);
            progress.remove();
            btn.classList.remove('loading');
            btn.innerHTML = '❌ Error - Try again';

            setTimeout(() => {
                btn.innerHTML = '⬇️ Download PDF';
            }, 3000);
        }
    }

    function init() {
        if (!window.location.hostname.includes('scribd.com')) return;

        setTimeout(() => {
            if (isEmbed()) {
                showEmbedButton();
            } else if (getDocId()) {
                showMainButton();
            }
        }, BUTTON_DELAY);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();