将网页漫画下载下来方便导入墨水屏电子书进行阅读
当前为
// ==UserScript==
// @name 网页漫画下载为epub/mobi/pdf等电子书格式
// @namespace http://tampermonkey.net/
// @version 1.1.0
// @description 将网页漫画下载下来方便导入墨水屏电子书进行阅读
// @author MornLight
// @match https://m.rumanhua.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=greasyfork.org
// @grant GM_xmlhttpRequest
// @require https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js
// @run-at document-end
// @license MIT
// @supportURL https://duanmorningsir.github.io/
// ==/UserScript==
(function () {
'use strict';
// 创建下载按钮和输入框
function createDownloadButton() {
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.bottom = '20px';
container.style.right = '20px';
container.style.zIndex = '1000';
container.style.display = 'flex';
container.style.flexDirection = 'column';
container.style.gap = '12px';
container.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
container.style.padding = '15px';
container.style.borderRadius = '5px';
container.style.boxShadow = '0 0 10px rgba(0,0,0,0.1)';
// 获取总页数
const totalPages = document.querySelectorAll('div.chapter-img-box').length;
// 起始页输入框
const startInput = document.createElement('input');
startInput.type = 'number';
startInput.min = '1';
startInput.max = totalPages;
startInput.value = '1';
startInput.placeholder = `起始页(1-${totalPages})`;
startInput.style.width = '120px';
startInput.style.padding = '8px';
startInput.style.border = '1px solid #ccc';
startInput.style.borderRadius = '5px';
startInput.style.textAlign = 'center';
startInput.style.fontSize = '14px';
// 结束页输入框
const endInput = document.createElement('input');
endInput.type = 'number';
endInput.min = '1';
endInput.max = totalPages;
endInput.value = totalPages; // 默认设为最大页数
endInput.placeholder = `结束页(1-${totalPages})`;
endInput.style.width = '120px';
endInput.style.padding = '8px';
endInput.style.border = '1px solid #ccc';
endInput.style.borderRadius = '5px';
endInput.style.textAlign = 'center';
endInput.style.fontSize = '14px';
// 添加输入验证
startInput.addEventListener('change', () => {
const startVal = parseInt(startInput.value);
const endVal = parseInt(endInput.value);
if (startVal < 1) {
alert('起始页不能小于1');
startInput.value = '1';
} else if (startVal > totalPages) {
alert(`起始页不能大于总页数${totalPages}`);
startInput.value = '1';
} else if (startVal > endVal) {
alert('起始页不能大于结束页');
startInput.value = endVal;
}
});
endInput.addEventListener('change', () => {
const startVal = parseInt(startInput.value);
const endVal = parseInt(endInput.value);
if (endVal > totalPages) {
alert(`结束页不能大于总页数${totalPages}`);
endInput.value = totalPages;
} else if (endVal < startVal) {
alert('结束页不能小于起始页');
endInput.value = startVal;
}
});
// 下载按钮
const downloadButton = document.createElement('button');
downloadButton.textContent = '下载指定范围漫画';
downloadButton.style.padding = '10px';
downloadButton.style.backgroundColor = '#007bff';
downloadButton.style.color = '#fff';
downloadButton.style.border = 'none';
downloadButton.style.borderRadius = '5px';
downloadButton.style.cursor = 'pointer';
// 全部下载按钮
const downloadAllButton = document.createElement('button');
downloadAllButton.textContent = '下载整个章节';
downloadAllButton.style.padding = '10px';
downloadAllButton.style.backgroundColor = '#28a745';
downloadAllButton.style.color = '#fff';
downloadAllButton.style.border = 'none';
downloadAllButton.style.borderRadius = '5px';
downloadAllButton.style.cursor = 'pointer';
// 添加事件监听
downloadButton.addEventListener('click', () => downloadComic(startInput.value, endInput.value));
downloadAllButton.addEventListener('click', () => downloadComic());
container.appendChild(startInput);
container.appendChild(endInput);
container.appendChild(downloadButton);
container.appendChild(downloadAllButton);
document.body.appendChild(container);
}
// 获取章节名称
function getChapterName() {
const chapterNameElement = document.querySelector('.chaphead-name h1');
return chapterNameElement ? chapterNameElement.textContent.trim() : '未知章节';
}
// 下载漫画
async function downloadComic(startPage, endPage) {
const chapterName = getChapterName();
const chapterImgBoxes = document.querySelectorAll('div.chapter-img-box');
const totalPages = chapterImgBoxes.length;
// 确定起始和结束页
const start = startPage ? parseInt(startPage, 10) : 1;
const end = endPage ? parseInt(endPage, 10) : totalPages;
// 验证页数
if (start > end || start < 1 || end > totalPages) {
alert(`请输入有效的页数范围!(1-${totalPages})`);
return;
}
// 创建 PDF 实例
const pdf = new jspdf.jsPDF();
// 并行下载图片
const downloadPromises = [];
chapterImgBoxes.forEach((box, index) => {
// 只下载指定范围内的图片
if (index + 1 >= start && index + 1 <= end) {
const img = box.querySelector('img');
if (img && img.dataset.src) {
const imgUrl = img.dataset.src;
downloadPromises.push(downloadImage(imgUrl, index - start + 1, pdf, end - start + 1));
}
}
});
// 等待所有图片下载完成
await Promise.all(downloadPromises);
// 保存 PDF 文件
const fileName = end === chapterImgBoxes.length && start === 1
? `${chapterName}_全部.pdf`
: `${chapterName}_${start}-${end}.pdf`;
pdf.save(fileName);
// 显示下载完成的提示
alert(`漫画《${chapterName}》第${start}至${end}页下载完成!`);
}
// 下载图片并添加到 PDF
function downloadImage(url, index, pdf, maxImages) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'GET',
url: url,
responseType: 'blob',
onload: function (response) {
try {
const blob = response.response;
const reader = new FileReader();
reader.onload = function (event) {
const imgData = event.target.result;
pdf.addImage(imgData, 'JPEG', 0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight());
if (index < maxImages - 1) {
pdf.addPage();
}
resolve();
};
reader.readAsDataURL(blob);
} catch (error) {
console.error('处理图片时出错:', error);
reject(error);
}
},
onerror: function (error) {
console.error('下载图片失败:', error);
reject(error);
}
});
});
}
// 创建下载按钮和输入框
createDownloadButton();
})();