您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Download books as txt from certain websites
// ==UserScript== // @name txt-downloader // @namespace https://github.com/LimboDzz/ // @version 1.0.0 // @description Download books as txt from certain websites // @author dzz // @match *://*.dmshuba.com/*n/*/*.html // @match *://*.yqshuwang.com/*n/*/*.html // @icon none // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; let downloadButton insertStyle() attachDownloadButton() function insertStyle() { const styles = ` body.processing { cursor: progress; } ` const styleSheet = document.createElement('style') styleSheet.innerText = styles document.head.append(styleSheet) } function attachDownloadButton() { //? createButton downloadButton = document.createElement('button') downloadButton.textContent = 'Download' downloadButton.setAttribute('style', ` position: fixed; right: 1em; bottom: 1em; `) downloadButton.addEventListener('click', download) document.body.append(downloadButton) } function download() { disableDownload() fetchAllPages() } function fetchAllPages() { let url = window.location.href //? remove the ending part of url // from https://www.dmshuba.com/2023n/03/91520_23.html // to https://www.dmshuba.com/2023n/03/91520 const [fileSpecifier,] = url.split(/(?=(_\d+)?.html)/) const filename = document.querySelector('h1').textContent.replace('\/', '_') const pageSum = document.querySelectorAll('a[title="Page"] b')[1].textContent //? get all page links to fetch const pageLinks = [] for (let i = 1; i <= pageSum; i++) { if (i == 1) url = `${fileSpecifier}.html` else url = `${fileSpecifier}_${i}.html` pageLinks.push(url) } Promise .all(pageLinks.map(pageLink => fetch(pageLink) .then(res => res.arrayBuffer()) .then(buffer => { //? res.text() default to utf-8 // resort to arrayBuffer and then TextDecoder const gb2312Decoder = new TextDecoder('gbk') const html = gb2312Decoder.decode(buffer) //? parse plain text to html for DOM manipulation const parser = new DOMParser() const doc = parser.parseFromString(html, 'text/html') const text = [...doc.querySelectorAll('#text div')] .map(div => div.childNodes[0].textContent) .join('\n') return text }) .catch(err => console.log('Failed to fetch page: ', err)) )) .then(textArray => saveFile(textArray, filename)) } function saveFile(textArray, filename) { //? create fileData const fileData = new Blob(textArray, { type: 'text/plain' }) //? create download link to that file const downloadLink = URL.createObjectURL(fileData) //? triger download const a = document.createElement('a') a.download = filename + '.txt' a.href = downloadLink a.click() a.remove() enableDownload() } function enableDownload() { downloadButton.addEventListener('click', download) downloadButton.textContent = 'Download' document.body.classList.toggle('processing') } function disableDownload() { downloadButton.removeEventListener('click', download) downloadButton.textContent = 'Processing...' document.body.classList.toggle('processing') } })();