Chapter Downloader

Extract content from truyen.tangthuvien.net

当前为 2025-03-09 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Chapter Downloader
// @namespace    http://tampermonkey.net/
// @version      0.9
// @description  Extract content from truyen.tangthuvien.net
// @author       You
// @match        https://truyen.tangthuvien.net/doc-truyen/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Create container for extracted content
    function createContainer() {
        // Check if container already exists
        if (document.getElementById('content-extractor')) {
            return;
        }

        const container = document.createElement('div');
        container.id = 'content-extractor';
        container.style.position = 'fixed';
        container.style.top = '0';
        container.style.right = '0';
        container.style.bottom = '0';
        container.style.width = '300px';
        container.style.backgroundColor = '#f5f5f5';
        container.style.padding = '15px';
        container.style.zIndex = '9999';
        container.style.boxShadow = '-2px 0 10px rgba(0,0,0,0.1)';
        container.style.overflow = 'auto';

        const title = document.createElement('h3');
        title.textContent = 'Nội dung truyện đã trích xuất';
        title.style.marginTop = '0';
        container.appendChild(title);

        const textarea = document.createElement('textarea');
        textarea.id = 'extracted-content';
        textarea.style.width = '100%';
        textarea.style.height = '150px';
        textarea.style.marginBottom = '10px';
        textarea.style.padding = '10px';
        textarea.style.boxSizing = 'border-box';
        
        // Load saved content if available
        const savedContent = localStorage.getItem('extractedNovelContent');
        if (savedContent) {
            textarea.value = savedContent;
        }
        
        // Auto-save content when it changes
        textarea.addEventListener('input', () => {
            localStorage.setItem('extractedNovelContent', textarea.value);
        });
        
        container.appendChild(textarea);

        const buttonContainer = document.createElement('div');
        buttonContainer.style.display = 'flex';
        buttonContainer.style.flexDirection = 'column';
        buttonContainer.style.gap = '10px';

        // Tạo nút "Bắt đầu lấy text"
        const startButton = document.createElement('button');
        startButton.textContent = 'Bắt đầu lấy text';
        startButton.style.padding = '10px 15px';
        startButton.style.backgroundColor = '#9c27b0';
        startButton.style.color = 'white';
        startButton.style.border = 'none';
        startButton.style.borderRadius = '4px';
        startButton.style.cursor = 'pointer';
        startButton.style.fontWeight = 'bold';
        
        // Thêm biến để kiểm soát quá trình tự động
        let isAutomaticExtraction = false;
        
        // Hàm đệ quy để tự động trích xuất và chuyển chương
        function autoExtractAndNavigate() {
            if (!isAutomaticExtraction) return;
            
            // Trích xuất nội dung chương hiện tại
            extractContent();
            
            // Tìm nút chuyển đến chương tiếp theo
            const nextButton = document.querySelector('.bot-next_chap.bot-control');
            
            // Kiểm tra xem có thông báo "Bạn đã đọc đến chương mới nhất" hay không
            const pageContent = document.body.innerText;
            if (pageContent.includes('Bạn đã đọc đến chương mới nhất')) {
                // Kết thúc quá trình khi thấy thông báo này
                isAutomaticExtraction = false;
                startButton.textContent = 'Bắt đầu lấy text';
                startButton.style.display = 'block';
                
                // Hiển thị thông báo hoàn thành
                const notification = document.createElement('div');
                notification.textContent = 'Đã hoàn thành trích xuất toàn bộ truyện!';
                notification.style.position = 'fixed';
                notification.style.bottom = '20px';
                notification.style.right = '320px';
                notification.style.backgroundColor = '#4caf50';
                notification.style.color = 'white';
                notification.style.padding = '10px';
                notification.style.borderRadius = '5px';
                notification.style.zIndex = '10000';
                document.body.appendChild(notification);
                
                // Xóa thông báo sau 5 giây
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 5000);
                return;
            }
            
            if (nextButton) {
                // Hiển thị thông báo
                const notification = document.createElement('div');
                notification.textContent = 'Đã lấy xong chương hiện tại, đang chuyển đến chương kế tiếp...';
                notification.style.position = 'fixed';
                notification.style.bottom = '20px';
                notification.style.right = '320px';
                notification.style.backgroundColor = '#2196f3';
                notification.style.color = 'white';
                notification.style.padding = '10px';
                notification.style.borderRadius = '5px';
                notification.style.zIndex = '10000';
                document.body.appendChild(notification);
                
                // Xóa thông báo sau 2 giây
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 2000);
                
                // Lấy liên kết của chương tiếp theo
                const nextChapterUrl = nextButton.href;
                
                // Chuyển đến chương tiếp theo
                window.location.href = nextChapterUrl;
                
                // Khi trang mới tải xong, khởi động lại quá trình
                // Sử dụng localStorage để truyền trạng thái giữa các trang
                localStorage.setItem('continueAutoExtract', 'true');
            } else {
                // Kết thúc quá trình khi không còn chương tiếp theo
                isAutomaticExtraction = false;
                startButton.textContent = 'Bắt đầu lấy text';
                startButton.style.display = 'block';
                
                // Hiển thị thông báo hoàn thành
                const notification = document.createElement('div');
                notification.textContent = 'Đã hoàn thành trích xuất toàn bộ truyện!';
                notification.style.position = 'fixed';
                notification.style.bottom = '20px';
                notification.style.right = '320px';
                notification.style.backgroundColor = '#4caf50';
                notification.style.color = 'white';
                notification.style.padding = '10px';
                notification.style.borderRadius = '5px';
                notification.style.zIndex = '10000';
                document.body.appendChild(notification);
                
                // Xóa thông báo sau 5 giây
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 5000);
            }
        }
        
        // Thêm sự kiện khi click vào nút bắt đầu
        startButton.addEventListener('click', function() {
            if (!isAutomaticExtraction) {
                // Bắt đầu quá trình tự động
                isAutomaticExtraction = true;
                startButton.textContent = 'Dừng trích xuất';
                
                // Hiển thị thông báo đã bắt đầu
                const notification = document.createElement('div');
                notification.textContent = 'Đã bắt đầu tự động trích xuất nội dung';
                notification.style.position = 'fixed';
                notification.style.bottom = '20px';
                notification.style.right = '320px';
                notification.style.backgroundColor = '#9c27b0';
                notification.style.color = 'white';
                notification.style.padding = '10px';
                notification.style.borderRadius = '5px';
                notification.style.zIndex = '10000';
                document.body.appendChild(notification);
                
                // Xóa thông báo sau 3 giây
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 3000);
                
                // Bắt đầu quá trình tự động
                autoExtractAndNavigate();
            } else {
                // Dừng quá trình tự động
                isAutomaticExtraction = false;
                startButton.textContent = 'Bắt đầu lấy text';
                
                // Hiển thị thông báo đã dừng
                const notification = document.createElement('div');
                notification.textContent = 'Đã dừng quá trình tự động trích xuất';
                notification.style.position = 'fixed';
                notification.style.bottom = '20px';
                notification.style.right = '320px';
                notification.style.backgroundColor = '#f44336';
                notification.style.color = 'white';
                notification.style.padding = '10px';
                notification.style.borderRadius = '5px';
                notification.style.zIndex = '10000';
                document.body.appendChild(notification);
                
                // Xóa thông báo sau 3 giây
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 3000);
            }
        });
        buttonContainer.appendChild(startButton);

        // Tạo các nút nhưng ẩn đi
        const extractButton = document.createElement('button');
        extractButton.textContent = 'Trích xuất nội dung trang hiện tại';
        extractButton.style.padding = '8px 15px';
        extractButton.style.backgroundColor = '#4caf50';
        extractButton.style.color = 'white';
        extractButton.style.border = 'none';
        extractButton.style.borderRadius = '4px';
        extractButton.style.cursor = 'pointer';
        extractButton.style.display = 'none'; // Ẩn nút
        extractButton.addEventListener('click', extractContent);
        buttonContainer.appendChild(extractButton);

        const nextChapterButton = document.createElement('button');
        nextChapterButton.textContent = 'Chuyển đến chương tiếp theo';
        nextChapterButton.style.padding = '8px 15px';
        nextChapterButton.style.backgroundColor = '#2196f3';
        nextChapterButton.style.color = 'white';
        nextChapterButton.style.border = 'none';
        nextChapterButton.style.borderRadius = '4px';
        nextChapterButton.style.cursor = 'pointer';
        nextChapterButton.style.display = 'none'; // Ẩn nút
        nextChapterButton.addEventListener('click', goToNextChapter);
        buttonContainer.appendChild(nextChapterButton);

        const clearButton = document.createElement('button');
        clearButton.textContent = 'Xóa nội dung';
        clearButton.style.padding = '8px 15px';
        clearButton.style.backgroundColor = '#f44336';
        clearButton.style.color = 'white';
        clearButton.style.border = 'none';
        clearButton.style.borderRadius = '4px';
        clearButton.style.cursor = 'pointer';
        clearButton.addEventListener('click', clearContent);
        buttonContainer.appendChild(clearButton);

        const copyButton = document.createElement('button');
        copyButton.textContent = 'Sao chép nội dung';
        copyButton.style.padding = '8px 15px';
        copyButton.style.backgroundColor = '#ff9800';
        copyButton.style.color = 'white';
        copyButton.style.border = 'none';
        copyButton.style.borderRadius = '4px';
        copyButton.style.cursor = 'pointer';
        copyButton.addEventListener('click', copyContent);
        buttonContainer.appendChild(copyButton);

        container.appendChild(buttonContainer);
        document.body.appendChild(container);
    }

    // Extract content from current page
    function extractContent() {
        const textarea = document.getElementById('extracted-content');
        
        // Get chapter title
        const chapterTitle = document.querySelector('h2');
        let titleText = chapterTitle ? chapterTitle.textContent.trim() : 'Không tìm thấy tiêu đề';
        
        // Get chapter content
        const chapterContentBox = document.querySelector('.box-chap');
        let contentText = '';
        
        if (chapterContentBox) {
            // Remove unwanted elements like scripts, styles, ads
            const contentClone = chapterContentBox.cloneNode(true);
            const scripts = contentClone.querySelectorAll('script, style, .ads, .banner, .comment');
            scripts.forEach(script => script.remove());
            
            // Get the clean text
            contentText = contentClone.innerText.trim();
        } else {
            contentText = 'Không tìm thấy nội dung chương';
        }
        
        // Append to existing content
        textarea.value += `\n\n${titleText}\n\n${contentText}`;
        
        // Save content to localStorage
        localStorage.setItem('extractedNovelContent', textarea.value);
        
        // Scroll to bottom of textarea
        textarea.scrollTop = textarea.scrollHeight;
    }

    // Go to next chapter
    function goToNextChapter() {
        const nextButton = document.querySelector('.bot-next_chap.bot-control');
        if (nextButton) {
            // Extract current content before moving to next chapter
            extractContent();
            
            // Navigate to next chapter
            nextButton.click();
            
            // Add a delay to let the next page load before extracting content
            setTimeout(() => {
                // Don't clear the textarea, just append the new content
                extractContent();
                
                // Show notification
                const notification = document.createElement('div');
                notification.textContent = 'Đã thêm nội dung chương mới';
                notification.style.position = 'fixed';
                notification.style.bottom = '20px';
                notification.style.right = '320px';
                notification.style.backgroundColor = '#4caf50';
                notification.style.color = 'white';
                notification.style.padding = '10px';
                notification.style.borderRadius = '5px';
                notification.style.zIndex = '10000';
                document.body.appendChild(notification);
                
                // Remove notification after 3 seconds
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 3000);
            }, 2000);
        } else {
            alert('Không tìm thấy nút chuyển đến chương tiếp theo');
        }
    }

    // Clear content in textarea
    function clearContent() {
        const textarea = document.getElementById('extracted-content');
        textarea.value = '';
        // Also clear the saved content
        localStorage.removeItem('extractedNovelContent');
    }

    // Copy content to clipboard
    function copyContent() {
        const textarea = document.getElementById('extracted-content');
        textarea.select();
        document.execCommand('copy');
        
        // Visual feedback
        const originalColor = textarea.style.backgroundColor;
        textarea.style.backgroundColor = '#e6ffe6';
        setTimeout(() => {
            textarea.style.backgroundColor = originalColor;
        }, 500);
    }

    // Initialize when page is loaded
    function init() {
        createContainer();
        
        // Kiểm tra xem có đang trong quá trình tự động trích xuất hay không
        const continueAutoExtract = localStorage.getItem('continueAutoExtract');
        if (continueAutoExtract === 'true') {
            // Xóa trạng thái để tránh lặp vô hạn nếu người dùng refresh trang
            localStorage.removeItem('continueAutoExtract');
            
            // Đợi một chút để trang tải hoàn toàn
            setTimeout(() => {
                // Kích hoạt quá trình tự động
                const startButton = document.querySelector('#content-extractor button');
                if (startButton && startButton.textContent === 'Bắt đầu lấy text') {
                    startButton.click();
                } else {
                    // Nếu không tìm thấy nút hoặc nút không đúng trạng thái,
                    // bắt đầu trực tiếp quá trình trích xuất
                    let isAutomaticExtraction = true;
                    
                    // Hiển thị thông báo đang đợi trang tải
                    const notification = document.createElement('div');
                    notification.textContent = 'Đợi trang tải xong...';
                    notification.style.position = 'fixed';
                    notification.style.bottom = '20px';
                    notification.style.right = '320px';
                    notification.style.backgroundColor = '#FFA500';
                    notification.style.color = 'white';
                    notification.style.padding = '10px';
                    notification.style.borderRadius = '5px';
                    notification.style.zIndex = '10000';
                    document.body.appendChild(notification);
                    
                    // Xóa thông báo và bắt đầu trích xuất sau 3 giây
                    setTimeout(() => {
                        document.body.removeChild(notification);
                        autoExtractAndNavigate();
                    }, 3000);
                }
            }, 1000);
        }
    }

    // Run when page is fully loaded
    window.addEventListener('load', init);
})();