您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Tải nội dung chương truyện từ TangThuVien
当前为
- // ==UserScript==
- // @name Chapter Downloader
- // @namespace http://tampermonkey.net/
- // @version 0.3
- // @description Tải nội dung chương truyện từ TangThuVien
- // @author Your name
- // @match https://truyen.tangthuvien.net/doc-truyen/*/*
- // @match https://truyen.tangthuvien.vn/doc-truyen/*/*
- // @match https://tangthuvien.vn/doc-truyen/*/*
- // @match https://tangthuvien.com/doc-truyen/*/*
- // @match https://*.tangthuvien.*/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 (tăng thời gian chờ lên 5 giây)
- console.log('Đợi 5 giây để nội dung tải hoàn tất...');
- await new Promise(resolve => setTimeout(resolve, 5000));
- // Tìm container chính - mở rộng bộ chọn để phù hợp với TangThuVien
- const mainContainer = document.querySelector('#article') ||
- document.querySelector('.content-chapter') ||
- document.querySelector('.chapter-content') ||
- document.querySelector('.box-chap') ||
- document.querySelector('.content') ||
- document.querySelector('.chapter');
- console.log('Container chính:', {
- found: !!mainContainer,
- id: mainContainer?.id,
- className: mainContainer?.className
- });
- // Nếu không tìm thấy container chính, thử tìm trực tiếp trong document
- // TangThuVien có thể không tuân theo cấu trúc container>tiêu đề+nội dung
- if (!mainContainer) {
- console.log('Không tìm thấy container chính, thử tìm trực tiếp trong document');
- }
- // Tìm tiêu đề
- const titleSelectors = [
- 'h2.chapter-title',
- '.chapter-title',
- '.truyen-title',
- 'h2.title',
- '.content-chapter h2',
- '.chapter h1',
- '.title-chapter',
- '.chapter-title h2',
- 'h1.title',
- 'header h1'
- ];
- let titleElement;
- // Tìm trong container chính nếu có
- if (mainContainer) {
- for (const selector of titleSelectors) {
- titleElement = mainContainer.querySelector(selector);
- if (titleElement?.textContent?.trim()) {
- console.log('Tìm thấy tiêu đề với selector trong container:', selector);
- break;
- }
- }
- }
- // Nếu không tìm thấy trong container, tìm trong toàn bộ document
- if (!titleElement || !titleElement?.textContent?.trim()) {
- for (const selector of titleSelectors) {
- titleElement = document.querySelector(selector);
- if (titleElement?.textContent?.trim()) {
- console.log('Tìm thấy tiêu đề với selector trong document:', selector);
- break;
- }
- }
- }
- // Tìm nội dung
- const contentSelectors = [
- '.chapter-c',
- '.chapter-content',
- '.content-chapter',
- '.box-chap',
- '.content',
- '#content',
- '.chapter-detail',
- '.chapter-text',
- '.chapter__content',
- '.ttv-chapter-content'
- ];
- let contentElement;
- // Tìm trong container chính nếu có
- if (mainContainer) {
- 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 trong container:', selector);
- break;
- }
- }
- }
- // Nếu không tìm thấy trong container, tìm trong toàn bộ document
- if (!contentElement || !contentElement?.textContent?.trim()) {
- for (const selector of contentSelectors) {
- contentElement = document.querySelector(selector);
- if (contentElement?.textContent?.trim()) {
- console.log('Tìm thấy nội dung với selector trong document:', selector);
- break;
- }
- }
- }
- // Xử lý trường hợp không tìm thấy tiêu đề hoặc nội dung
- if (!titleElement && !contentElement) {
- console.error('Không tìm thấy cả tiêu đề và nội dung');
- // Thử phương pháp cuối cùng - lấy toàn bộ văn bản của trang
- const bodyText = document.body.innerText;
- if (bodyText && bodyText.length > 500) { // Giả sử trang có ít nhất 500 ký tự
- console.log('Thử phương pháp cuối cùng - lấy toàn bộ văn bản');
- // Lấy tiêu đề từ thẻ title của trang
- const pageTitle = document.title.trim();
- return {
- title: pageTitle,
- content: bodyText
- };
- }
- throw new Error('Không tìm thấy nội dung hoặc tiêu đề');
- }
- if (!titleElement) {
- console.log('Không tìm thấy tiêu đề, sử dụng title của trang');
- const pageTitle = document.title.trim();
- titleElement = { textContent: pageTitle };
- }
- if (!contentElement) {
- console.error('Không tìm thấy nội dung:', {
- hasTitle: !!titleElement,
- titleHTML: titleElement?.outerHTML
- });
- throw new Error('Không tìm thấy nội dung');
- }
- console.log('Tìm thấy cả tiêu đề và nội dung:', {
- hasTitle: !!titleElement,
- hasContent: !!contentElement,
- titlePreview: titleElement?.textContent?.trim().substring(0, 50),
- contentPreview: contentElement?.textContent?.trim().substring(0, 100)
- });
- // 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, ''); // Xóa tất cả nội dung trong ngoặc vuông
- 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
- // Loại bỏ các đoạn quảng cáo phổ biến
- content = content.replace(/Truyện\s+VIP\s+\S+/gi, '');
- content = content.replace(/Đọc\s+truyện\s+tại\s+\S+/gi, '');
- content = content.replace(/Tham\s+gia\s+group\s+\S+/gi, '');
- content = content.replace(/nguồn\s*:\s*\S+/gi, '');
- 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');
- })();