Chapter Downloader

Tự động trích xuất nội dung truyện từ truyen.tangthuvien.net

目前為 2025-03-09 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Chapter Downloader
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Tự động trích xuất nội dung truyện từ truyen.tangthuvien.net
// @author       TangThuVienExtractor
// @match        https://truyen.tangthuvien.net/doc-truyen/*/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Biến toàn cục để theo dõi trạng thái trích xuất tự động
    let isAutomaticExtraction = false;

    // Tạo panel ở bên phải trang
    function createPanel() {
        // Tạo container chính cho panel
        const panel = document.createElement('div');
        panel.style.position = 'fixed';
        panel.style.top = '100px';
        panel.style.right = '20px';
        panel.style.width = '300px';
        panel.style.backgroundColor = '#f9f9f9';
        panel.style.border = '1px solid #ddd';
        panel.style.borderRadius = '5px';
        panel.style.padding = '10px';
        panel.style.zIndex = '9999';
        panel.style.display = 'flex';
        panel.style.flexDirection = 'column';
        panel.style.gap = '10px';
        panel.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.1)';

        // Tạo tiêu đề panel
        const title = document.createElement('h3');
        title.textContent = 'Trích xuất nội dung truyện';
        title.style.margin = '0 0 10px 0';
        title.style.textAlign = 'center';
        title.style.borderBottom = '1px solid #ddd';
        title.style.paddingBottom = '10px';
        panel.appendChild(title);

        // Tạo textarea để hiển thị nội dung đã trích xuất
        const textarea = document.createElement('textarea');
        textarea.style.width = '100%';
        textarea.style.height = '200px';
        textarea.style.padding = '8px';
        textarea.style.borderRadius = '3px';
        textarea.style.border = '1px solid #ddd';
        textarea.style.marginBottom = '10px';
        textarea.style.resize = 'vertical';
        panel.appendChild(textarea);

        // Lấy nội dung đã lưu từ localStorage (nếu có)
        const savedContent = localStorage.getItem('tangthuvien_extracted_content');
        if (savedContent) {
            textarea.value = savedContent;
        }

        // Tạo container cho các nút
        const buttonContainer = document.createElement('div');
        buttonContainer.style.display = 'flex';
        buttonContainer.style.flexDirection = 'column';
        buttonContainer.style.gap = '5px';
        panel.appendChild(buttonContainer);

        // Tạo nút bắt đầu trích xuất
        const startButton = document.createElement('button');
        startButton.textContent = 'Bắt đầu lấy text';
        startButton.style.padding = '8px';
        startButton.style.backgroundColor = '#4caf50';
        startButton.style.color = 'white';
        startButton.style.border = 'none';
        startButton.style.borderRadius = '3px';
        startButton.style.cursor = 'pointer';
        startButton.addEventListener('click', function() {
            if (!isAutomaticExtraction) {
                isAutomaticExtraction = true;
                startButton.textContent = 'Đang trích xuất...';
                startButton.style.backgroundColor = '#ff9800';
                
                // Bắt đầu quá trình trích xuất tự động
                autoExtractAndNavigate();
            } else {
                isAutomaticExtraction = false;
                startButton.textContent = 'Bắt đầu lấy text';
                startButton.style.backgroundColor = '#4caf50';
            }
        });
        buttonContainer.appendChild(startButton);

        // Tạo nút xóa nội dung
        const clearButton = document.createElement('button');
        clearButton.textContent = 'Xóa nội dung';
        clearButton.style.padding = '8px';
        clearButton.style.backgroundColor = '#f44336';
        clearButton.style.color = 'white';
        clearButton.style.border = 'none';
        clearButton.style.borderRadius = '3px';
        clearButton.style.cursor = 'pointer';
        clearButton.addEventListener('click', function() {
            textarea.value = '';
            localStorage.removeItem('tangthuvien_extracted_content');
            
            // Hiển thị thông báo
            const notification = document.createElement('div');
            notification.textContent = 'Đã xóa nội dung';
            notification.style.position = 'fixed';
            notification.style.bottom = '20px';
            notification.style.right = '20px';
            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(clearButton);

        // Tạo nút sao chép nội dung
        const copyButton = document.createElement('button');
        copyButton.textContent = 'Sao chép nội dung';
        copyButton.style.padding = '8px';
        copyButton.style.backgroundColor = '#2196f3';
        copyButton.style.color = 'white';
        copyButton.style.border = 'none';
        copyButton.style.borderRadius = '3px';
        copyButton.style.cursor = 'pointer';
        copyButton.addEventListener('click', function() {
            textarea.select();
            document.execCommand('copy');
            
            // Hiển thị thông báo
            const notification = document.createElement('div');
            notification.textContent = 'Đã sao chép nội dung';
            notification.style.position = 'fixed';
            notification.style.bottom = '20px';
            notification.style.right = '20px';
            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 3 giây
            setTimeout(() => {
                document.body.removeChild(notification);
            }, 3000);
        });
        buttonContainer.appendChild(copyButton);

        // Thêm panel vào body
        document.body.appendChild(panel);
        
        // Trả về các phần tử để sử dụng sau này
        return {
            panel,
            textarea,
            startButton
        };
    }

    // Hàm trích xuất nội dung chương hiện tại
    function extractCurrentChapterContent() {
        const panelElements = document.querySelector('textarea');
        const startButton = document.querySelector('button');
        
        if (!panelElements || !startButton) {
            console.error('Không tìm thấy panel hoặc textarea');
            return false;
        }
        
        // Lấy tiêu đề chương
        const chapterTitle = document.querySelector('h2');
        if (!chapterTitle) {
            console.error('Không tìm thấy tiêu đề chương');
            return false;
        }
        
        // Lấy nội dung chương
        const chapterContentSelector = '.box-chap';
        const chapterContent = document.querySelector(chapterContentSelector);
        if (!chapterContent) {
            console.error('Không tìm thấy nội dung chương');
            return false;
        }
        
        // Xử lý nội dung
        let contentText = chapterContent.innerText || chapterContent.textContent;
        contentText = contentText.trim();
        
        // Thêm nội dung vào textarea
        let currentContent = panelElements.value || '';
        
        // Thêm dấu phân cách nếu đã có nội dung trước đó
        if (currentContent !== '') {
            currentContent += '\n\n------------\n\n';
        }
        
        // Thêm tiêu đề và nội dung
        currentContent += chapterTitle.innerText + '\n\n' + contentText;
        
        // Cập nhật textarea và lưu vào localStorage
        panelElements.value = currentContent;
        localStorage.setItem('tangthuvien_extracted_content', currentContent);
        
        // Hiển thị thông báo
        const notification = document.createElement('div');
        notification.textContent = 'Đã trích xuất: ' + chapterTitle.innerText;
        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 3 giây
        setTimeout(() => {
            document.body.removeChild(notification);
        }, 3000);
        
        return true;
    }

    // Hàm tự động trích xuất và chuyển trang
    function autoExtractAndNavigate() {
        if (!isAutomaticExtraction) {
            return;
        }
        
        // Trích xuất nội dung chương hiện tại
        const extractionSuccess = extractCurrentChapterContent();
        
        if (extractionSuccess) {
            // 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;
                const startButton = document.querySelector('button');
                if (startButton) {
                    startButton.textContent = 'Bắt đầu lấy text';
                    startButton.style.backgroundColor = '#4caf50';
                }
                
                // 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 = 'Đang chuyển đến chương tiếp theo...';
                notification.style.position = 'fixed';
                notification.style.bottom = '20px';
                notification.style.right = '320px';
                notification.style.backgroundColor = '#ff9800';
                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);
                
                // Nhấp vào nút chuyển trang
                nextButton.click();
                
                // Đợi 2 giây để trang mới tải xong, sau đó tiếp tục quá trình
                setTimeout(() => {
                    // Kiểm tra xem nút có bị ẩn hay không
                    const startButton = document.querySelector('button');
                    
                    // 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
                    
                    // 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 2 giây
                    setTimeout(() => {
                        document.body.removeChild(notification);
                        autoExtractAndNavigate();
                    }, 2000);
                }, 1000);
            } else {
                // Nếu không tìm thấy nút chuyển trang
                isAutomaticExtraction = false;
                const startButton = document.querySelector('button');
                if (startButton) {
                    startButton.textContent = 'Bắt đầu lấy text';
                    startButton.style.backgroundColor = '#4caf50';
                }
                
                // Hiển thị thông báo
                const notification = document.createElement('div');
                notification.textContent = 'Không tìm thấy nút chuyển trang';
                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 5 giây
                setTimeout(() => {
                    document.body.removeChild(notification);
                }, 5000);
            }
        } else {
            // Nếu trích xuất thất bại
            isAutomaticExtraction = false;
            const startButton = document.querySelector('button');
            if (startButton) {
                startButton.textContent = 'Bắt đầu lấy text';
                startButton.style.backgroundColor = '#4caf50';
            }
            
            // Hiển thị thông báo
            const notification = document.createElement('div');
            notification.textContent = 'Trích xuất thất bại';
            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 5 giây
            setTimeout(() => {
                document.body.removeChild(notification);
            }, 5000);
        }
    }

    // Khởi tạo panel khi trang đã tải xong
    window.addEventListener('load', function() {
        // Đợi 1 giây để đảm bảo trang đã tải hoàn toàn
        setTimeout(() => {
            createPanel();
        }, 1000);
    });
})();