Trích xuất toàn bộ chương truyện

Tải tất cả các chương từ trang danh sách chương truyen.tangthuvien.vn

目前为 2025-04-21 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Trích xuất toàn bộ chương truyện
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.1
  5. // @description Tải tất cả các chương từ trang danh sách chương truyen.tangthuvien.vn
  6. // @match https://truyen.tangthuvien.vn/doc-truyen/*
  7. // @grant GM_xmlhttpRequest
  8. // @connect truyen.tangthuvien.vn
  9. // ==/UserScript==
  10.  
  11. (function () {
  12. 'use strict';
  13.  
  14. // Giao diện
  15. const panel = document.createElement('div');
  16. panel.style.cssText = 'position:fixed;top:10%;right:10px;width:300px;background:#fff;border:1px solid #ccc;padding:10px;z-index:9999;font-family:sans-serif;';
  17. panel.innerHTML = `
  18. <textarea id="outputText" style="width:100%;height:300px;margin-bottom:10px;"></textarea>
  19. <button id="startBtn" style="width:100%;padding:5px 0;margin-bottom:5px;">Bt đầu ti</button>
  20. <button id="copyBtn" style="width:100%;padding:5px 0;">Sao chép</button>
  21. `;
  22. document.body.appendChild(panel);
  23.  
  24. const textarea = document.getElementById('outputText');
  25. const startBtn = document.getElementById('startBtn');
  26. const copyBtn = document.getElementById('copyBtn');
  27.  
  28. function sleep(ms) {
  29. return new Promise(resolve => setTimeout(resolve, ms));
  30. }
  31.  
  32. async function fetchChapter(url) {
  33. return new Promise((resolve) => {
  34. GM_xmlhttpRequest({
  35. method: "GET",
  36. url: url,
  37. onload: function (response) {
  38. const html = response.responseText;
  39. const parser = new DOMParser();
  40. const doc = parser.parseFromString(html, 'text/html');
  41. const title = doc.querySelector('h2')?.innerText.trim() || 'Không tiêu đề';
  42. const content = doc.querySelector('.box-chap')?.innerText.trim() || 'Không có nội dung';
  43. resolve(`\n\n------------\n\n${title}\n\n${content}`);
  44. }
  45. });
  46. });
  47. }
  48.  
  49. async function startDownload() {
  50. const links = [...document.querySelectorAll('a[href*="/chuong-"]')]
  51. .filter(a => a.href && !a.href.includes('javascript:void'));
  52.  
  53. if (links.length === 0) {
  54. alert("Không tìm thấy chương nào.");
  55. return;
  56. }
  57.  
  58. startBtn.disabled = true;
  59. for (let i = 0; i < links.length; i++) {
  60. const url = links[i].href;
  61. textarea.value += `\nĐang ti: ${url}\n`;
  62. const data = await fetchChapter(url);
  63. textarea.value += data;
  64. await sleep(1000); // delay giữa các chương
  65. }
  66.  
  67. alert('Hoàn tất!');
  68. startBtn.disabled = false;
  69. }
  70.  
  71. startBtn.addEventListener('click', startDownload);
  72. copyBtn.addEventListener('click', () => {
  73. textarea.select();
  74. document.execCommand('copy');
  75. alert('Đã sao chép nội dung!');
  76. });
  77. })();