您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
tsadult post saver
// ==UserScript== // @name tsadult-dl // @namespace http://tampermonkey.net/ // @version 0.3.1 // @description tsadult post saver // @author You // @match https://*.tsadult.net/*/res/*.html // @icon https://www.google.com/s2/favicons?sz=64&domain=tsadult.net // @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.8.0/jszip.min.js // @grant GM_addStyle // @license MIT // ==/UserScript== const CSS = ` #dl-btn { position: fixed; bottom: 64px; right: 32px; font-size: 16pt; text-align: right; } #dl-msg { font-size: 12pt; color: black; } ` function addDownloadButton() { var count = 0; const post = getPost(); const imageTask = post.filter(it => it.image != null); const container = document.createElement('div'); container.id = 'dl-btn'; const message = document.createElement('div'); message.id = 'dl-msg'; const printMessage = (msg) => { message.innerText = msg }; printMessage(`image: (0/${imageTask.length})`); const button = document.createElement('button'); button.innerText = '💾'; button.onclick = () => { if (downloading) { return; } var downloading = true; console.log('get post', post); var zip = new JSZip(); var tasks = imageTask.map(it => { const name = it.image.name; const url = it.image.url; console.log('download image', it); return fetch(url) .then(resp => resp.blob()) .then(blob => { zip.file(name, blob); count++; printMessage(`image: (${count}/${imageTask.length})`); return Promise.resolve(); }) }); const article = post.map(it => it.content) .filter(it => it!=null && it.length > 0) .join('\n\r---\n\r'); Promise.all(tasks) .then(() => zip.file('article.md', article)) .then(() => zip.generateAsync({ type: 'blob' })) .then(blob => { const download = document.createElement('a'); document.body.appendChild(download); download.style.display = 'none'; const fileUrl = window.URL.createObjectURL(blob); download.href = fileUrl; download.download = 'tsadult_' + new Date().getTime(); download.click(); window.URL.revokeObjectURL(fileUrl); download.remove(); downloading = false; }) } container.appendChild(message); container.appendChild(button); return container; } const parser = { old: function () { const convertTo = function (fragment) { const message = fragment.querySelector('.message'); var content = message?.innerText?.replace(/^#/gm, '> '); var image = null; const img = fragment.querySelector('img'); if (img) { const url = new URL(img.parentElement.href, location.href).href.toString(); const suffixIndex = url.lastIndexOf('/'); image = { url, name: url.slice(suffixIndex + 1) } content = `\n\n` + content; } return { image, content } }; const post = document.querySelector('.op'); const tables = document.querySelectorAll('#posts > table'); const contents = Array.from(tables).map(it => convertTo(it)); return [convertTo(post), ...contents] }, v2024: function () { const convertTo = function (fragment) { const imagesEle = fragment.querySelectorAll('.files .fileinfo > a'); const images = Array.from(imagesEle) .map(e => { const url = new URL(e.href, location.href).href.toString(); const name = e.innerText; const image = { url, name }; const content = `\n\n`; return { image, content } }); const text = fragment.querySelector('.body')?.innerText?.replace(/^#/gm, '> ') ?? ''; return [...images, { image: null, content: text }] }; const imagesEle = document.querySelectorAll('.thread > .files .fileinfo > a'); const images = Array.from(imagesEle) .map(e => { const url = new URL(e.href, location.href).href.toString(); const name = e.innerText; const image = { url, name }; const content = ``; return { image, content } }); const posts = Array.from(document.querySelectorAll('.thread > .post')) .map(e => convertTo(e)) .flat(); return [...images, ...posts] } }; function getPost() { const url = location.host; if (url.includes('2021')) { return parser.old() } else { return parser.v2024() } } (function () { 'use strict'; GM_addStyle(CSS); const button = addDownloadButton(); document.body.appendChild(button); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址