您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Sleazy Fork is available in English.
Scrapes the links of your Nhentai favorites list and saves them as a text file.
// ==UserScript== // @name Nhentai Favorites Exporter // @version 1.0 // @description Scrapes the links of your Nhentai favorites list and saves them as a text file. // @match *://nhentai.net/favorites/* // @author Adam Jensen // @license MIT // @grant none // @run-at document-idle // @namespace https://greasyfork.org/users/1398884 // ==/UserScript== const sleepInterval = 200; const loadTimeout = 5000; let isRunning = false; function download(filename, text) { const element = document.createElement('a'); element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); element.setAttribute('download', filename); document.body.appendChild(element); element.click(); document.body.removeChild(element); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function getLocalStorageLinks() { try { const links = JSON.parse(localStorage.getItem('parser-links')) || []; return new Set(links); } catch (e) { console.error('Error parsing links from localStorage:', e); return new Set(); } } function setLocalStorageLinks(links) { try { localStorage.setItem('parser-links', JSON.stringify([...links])); } catch (e) { console.error('Error saving links to localStorage:', e); } } function clearLocalStorageLinks() { localStorage.removeItem('parser-links'); } function getState() { return localStorage.getItem('parser-state') || '0'; } function setState(state) { localStorage.setItem('parser-state', state); } function updateCounter(count) { const counterElement = document.getElementById('scrape-counter'); if (counterElement) { counterElement.textContent = `Links scraped: ${count}`; } } function createButton(text, onClickHandler) { const button = document.createElement('button'); button.textContent = text; button.onclick = onClickHandler; button.style.marginRight = '10px'; return button; } function replaceButton(newButtonText, onClickHandler) { const buttonContainer = document.querySelector('.menu.right').children[0].children[0]; if (buttonContainer && buttonContainer.textContent !== newButtonText) { const button = createButton(newButtonText, onClickHandler); buttonContainer.replaceWith(button); } } function activateParser() { clearLocalStorageLinks(); setState('1'); processFavorites(); } function deactivateParser() { const links = getLocalStorageLinks(); const plainText = [...links].join('\n'); download('favorites.txt', plainText); setState('0'); } function stopScraping() { isRunning = false; setState('0'); replaceButton('Start Scraping', activateParser); } async function processFavorites() { if (isRunning) return; isRunning = true; const links = getLocalStorageLinks(); let count = links.size; updateCounter(count); async function scrapePage() { if (!isRunning) return; try { Array.from(document.getElementsByClassName('gallery-favorite')).forEach(fav => { const link = 'https://nhentai.net/g/' + fav.dataset.id + '/'; if (!links.has(link)) { links.add(link); count++; updateCounter(count); } }); setLocalStorageLinks(links); await sleep(sleepInterval); const nextButton = document.querySelector('.next'); if (nextButton) { nextButton.click(); await sleep(loadTimeout); scrapePage(); } else { deactivateParser(); replaceButton('DONE', () => {}); } } catch (e) { console.error('Error during scraping:', e); deactivateParser(); replaceButton('ERROR', () => {}); } } scrapePage(); } function init() { if (getState() === '0') { replaceButton('Start Scraping', activateParser); } else { replaceButton('Stop and Save', deactivateParser); const cancelButton = createButton('Cancel Scraping', stopScraping); document.querySelector('.menu.right').children[0].appendChild(cancelButton); const counterDiv = document.createElement('div'); counterDiv.id = 'scrape-counter'; counterDiv.textContent = 'Links scraped: 0'; document.querySelector('.menu.right').appendChild(counterDiv); processFavorites(); } } init();