您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Tải nội dung chương truyện từ TangThuVien
当前为
// ==UserScript== // @name Chapter Downloader // @namespace http://tampermonkey.net/ // @version 0.2 // @description Tải nội dung chương truyện từ TangThuVien // @author Your name // @match https://truyen.tangthuvien.net/doc-truyen/*/* // @grant GM_addStyle // ==/UserScript== (function() { 'use strict'; // Thêm CSS cho khung soạn thảo GM_addStyle(` .story-editor-container { position: fixed; top: 20px; right: 20px; width: 400px; height: 80vh; background: white; border: 1px solid #ccc; padding: 10px; z-index: 9999; display: flex; flex-direction: column; gap: 10px; } .story-editor { flex: 1; width: 100%; resize: none; font-family: Arial, sans-serif; font-size: 14px; line-height: 1.6; padding: 10px; } .button-container { display: flex; gap: 10px; } button { padding: 8px 16px; cursor: pointer; background: #4CAF50; color: white; border: none; border-radius: 4px; } button:hover { background: #45a049; } .status-text { font-size: 12px; color: #666; } `); // Log tất cả các elements có thể chứa nội dung function logPossibleElements() { const elements = document.querySelectorAll('*'); const contentElements = Array.from(elements).filter(el => { const text = el.textContent?.trim(); return text && text.length > 100; }); console.log('Các elements có thể chứa nội dung:', contentElements.map(el => ({ tagName: el.tagName, className: el.className, id: el.id, textLength: el.textContent?.trim().length, firstChars: el.textContent?.trim().substring(0, 50) })) ); } // Lấy nội dung chương hiện tại async function getCurrentChapter() { try { console.log('Bắt đầu lấy nội dung chương...'); logPossibleElements(); // Đợi nội dung tải xong await new Promise(resolve => setTimeout(resolve, 3000)); // Tìm container chính const mainContainer = document.querySelector('#article') || document.querySelector('.content-chapter') || document.querySelector('.chapter-content'); console.log('Container chính:', { found: !!mainContainer, id: mainContainer?.id, className: mainContainer?.className }); if (!mainContainer) { throw new Error('Không tìm thấy container chính'); } // Tìm tiêu đề const titleSelectors = [ 'h2.chapter-title', '.chapter-title', '.truyen-title', 'h2.title', '.content-chapter h2' ]; let titleElement; for (const selector of titleSelectors) { titleElement = mainContainer.querySelector(selector); if (titleElement?.textContent?.trim()) { console.log('Tìm thấy tiêu đề với selector:', selector); break; } } // Tìm nội dung const contentSelectors = [ '.chapter-c', '.chapter-content', '.content-chapter', '.box-chap' ]; let contentElement; for (const selector of contentSelectors) { contentElement = mainContainer.querySelector(selector); if (contentElement?.textContent?.trim()) { console.log('Tìm thấy nội dung với selector:', selector); break; } } if (!titleElement || !contentElement) { console.error('Không tìm thấy nội dung:', { hasTitle: !!titleElement, hasContent: !!contentElement, titleHTML: titleElement?.outerHTML, contentPreview: contentElement?.textContent?.trim().substring(0, 100) }); throw new Error('Không tìm thấy nội dung hoặc tiêu đề'); } // Xử lý nội dung let title = titleElement.textContent.trim(); let content = contentElement.textContent.trim(); // Làm sạch nội dung content = content.replace(title, ''); // Xóa tiêu đề khỏi nội dung content = content.replace(/\[\s*\w+\s*\]/g, ''); // Xóa [xxx] content = content.replace(/[""]/g, '"'); // Chuẩn hóa dấu ngoặc kép content = content.replace(/\s+/g, ' ').trim(); // Chuẩn hóa khoảng trắng console.log('Đã lấy nội dung:', { title, contentLength: content.length, contentPreview: content.substring(0, 100) + '...' }); return { title, content }; } catch (error) { console.error('Lỗi khi lấy nội dung:', error); return null; } } // Thêm nội dung chương mới vào editor function appendChapterContent(editor, title, content) { try { if (!editor || !title || !content) { console.error('Input không hợp lệ:', { hasEditor: !!editor, hasTitle: !!title, hasContent: !!content }); return false; } // Thêm dấu phân cách nếu đã có nội dung const separator = editor.value ? '\n\n' + '-'.repeat(50) + '\n\n' : ''; const newContent = title + '\n\n' + content; // Nối tiếp nội dung vào cuối editor.value += separator + newContent; editor.scrollTop = editor.scrollHeight; console.log('Đã thêm nội dung:', { previousLength: editor.value.length - (separator + newContent).length, addedLength: newContent.length, newTotalLength: editor.value.length }); return true; } catch (error) { console.error('Lỗi khi thêm nội dung:', error); return false; } } // Chuyển đến chương tiếp theo function goToNextChapter() { const nextButton = document.querySelector('a.next-chap'); if (nextButton && !nextButton.classList.contains('disabled') && nextButton.style.display !== 'none') { console.log('Chuyển đến chương tiếp theo'); nextButton.click(); return true; } console.log('Không tìm thấy nút next hợp lệ'); return false; } // Tải chương tiếp theo async function loadNextChapter() { try { console.log('Bắt đầu tải chương tiếp...'); const editor = document.querySelector('.story-editor'); if (!editor) { throw new Error('Không tìm thấy editor'); } // Đợi nội dung tải const chapterData = await getCurrentChapter(); if (!chapterData) { throw new Error('Không lấy được nội dung chương'); } // Thêm nội dung vào editor if (!appendChapterContent(editor, chapterData.title, chapterData.content)) { throw new Error('Không thêm được nội dung vào editor'); } // Tự động tải chương tiếp setTimeout(() => { if (goToNextChapter()) { setTimeout(loadNextChapter, 3000); } }, 1000); } catch (error) { console.error('Lỗi khi tải chương:', error); } } // Xuất nội dung ra file txt function exportToTxt() { try { const editor = document.querySelector('.story-editor'); if (!editor?.value) { throw new Error('Không có nội dung để xuất'); } const blob = new Blob([editor.value], { type: 'text/plain;charset=utf-8' }); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); const storyName = window.location.pathname.split('/')[2] || 'truyen'; link.href = url; link.download = `${storyName}.txt`; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); console.log('Đã xuất file thành công'); } catch (error) { console.error('Lỗi khi xuất file:', error); } } // Tạo giao diện function createUI() { console.log('Tạo giao diện...'); const container = document.createElement('div'); container.className = 'story-editor-container'; const editor = document.createElement('textarea'); editor.className = 'story-editor'; editor.placeholder = 'Nội dung truyện sẽ hiển thị ở đây...'; editor.readOnly = true; const buttonContainer = document.createElement('div'); buttonContainer.className = 'button-container'; const downloadBtn = document.createElement('button'); downloadBtn.textContent = 'Tải chương tiếp'; downloadBtn.onclick = loadNextChapter; const exportBtn = document.createElement('button'); exportBtn.textContent = 'Xuất file TXT'; exportBtn.onclick = exportToTxt; buttonContainer.appendChild(downloadBtn); buttonContainer.appendChild(exportBtn); container.appendChild(editor); container.appendChild(buttonContainer); document.body.appendChild(container); console.log('Đã tạo giao diện thành công'); } // Khởi tạo script if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', createUI); } else { createUI(); } console.log('TangThuVien Chapter Downloader đã khởi chạy'); })();