Greasy Fork is available in English.
下载 mhgui.com 和 omanhua.net 的漫画,保存到浏览器的下载文件夹里。从任意页面下载皆可,会一直下载到最后一页(自动跨章节下载)
// ==UserScript== // @name mhgui & omanhua Downloader 仙尊 漫画柜、哦漫画 下载器 // @namespace http://saber.love/?p=3407 // @version 3.5 // @description 下载 mhgui.com 和 omanhua.net 的漫画,保存到浏览器的下载文件夹里。从任意页面下载皆可,会一直下载到最后一页(自动跨章节下载) // @author 雪见仙尊 // @match https://*.manhuagui.com/comic/* // @match https://*.mhgui.com/comic/* // @match http://*.omanhua.com/comic/* // @match http://*.omanhua.net/comic/* // @license GNU General Public License version 3 // @icon https://www.mhgui.com/favicon.ico // @grant GM_xmlhttpRequest // @grant GM_download // @connect dx.yogajx.com // @connect i.yogajx.com // @connect p.yogajx.com // @connect i.hamreus.com // @connect dx.hamreus.com // @connect p.szhkshop.com // @connect pic.fxdm.cc // @connect us.hamreus.com // @connect static.7jfb.cn // @connect eu.hamreus.com // @connect * // @run-at document-end // ==/UserScript== /** * 作者:雪见仙尊 * 博客:https://saber.love/ * QQ群:499873152 * 3.0更新:manhuagui.com 设置了 X-Frame-Options: DENY,导致无法使用iframe来加载了,只好改成直接从页面抓取。 * 现在有个已知的问题,每一章的最后一页有可能下载两次 */ let isMHG = false; //区分漫画柜和哦漫画 if (location.hostname.includes('.manhuagui.com') || location.hostname.includes('.mhgui.com')) { isMHG = true } let splitString = isMHG ? '#' : '?'; // 根据站点设置分页符 let safe_fileName_rule = new RegExp(/\\|\/|:|\?|"|<|>|\*|\|/g); // 安全的文件名 let comicName = document.querySelector('h1 a').innerHTML; //漫画名 let pageTotal = document.querySelectorAll('option').length; // 总页数 let userStop, output, outputE, hui; let sessionKey = 'continueDown'; let timer_dealy = isMHG ? 500 : 1000; function setDownloadStatus (boolean) { if (boolean) { sessionStorage.setItem(sessionKey, 'yes'); } else { sessionStorage.removeItem(sessionKey); } // sessionStorage 对当前标签页生效(对从当前标签页里打开的页面也生效)。标签页关闭后自动清除。可以解决用户不经过确认直接关闭页面时,没有正常解锁的情况 } // 创建开始按钮 let startDownload = document.createElement('a'); startDownload.id = 'startDownload'; startDownload.className = 'btn-red'; startDownload.innerHTML = '开始下载'; document.querySelector('.main-btn').appendChild(startDownload); startDownload.style.background = '#0077D1'; startDownload.style.cursor = 'pointer'; // 创建下载 a 标签 let down_a = `<a href="" id="down_a" download></a>`; document.body.insertAdjacentHTML('beforeend', down_a); down_a = document.getElementById('down_a'); function addOutput () { // 创建用于输出提示信息的区域 output = document.createElement('div'); output.id = 'output'; document.body.insertBefore(output, document.querySelector('.title')); document.querySelector('#output').style.cssText = 'width:960px;margin:0 auto;backgroundColor:#fff;padding:10px;fontSize:14px;'; document.querySelector('#output').addEventListener('click', () => { if (!userStop) { if (confirm('你确定要停止下载吗?')) { userStop = true; setDownloadStatus(false); alert('下载已停止。'); } } }); outputE = document.querySelector('#output'); } function GMDownload () { // 用于下载图片 let imgUrl = document.querySelector('.mangaFile').getAttribute('src'); //图片网址 if (imgUrl.includes('[') || imgUrl.includes(']')) { //如果url里含有[]这两个符号,会被encodeURI编码掉。所以encodeURI之后要在转换回来(我在这地方被坑了数小时)。但为什么下边还要再encodeURI一次?不经过二次encodeURI就不行,我也是好晕啊 imgUrl = (encodeURI(imgUrl).replace(/%5B/g, '[')).replace(/%5D/g, ']'); } else if (imgUrl.includes('%') && imgUrl.includes('%26') === false) { //如果含有已经转码过的汉字,就全解码成汉字,再编码。%26是排除&符号。但为什么还是需要第二次编码? imgUrl = encodeURI(decodeURI(imgUrl)); } else { //虽然不知道为什么,总之编码两次就对了 imgUrl = encodeURI(imgUrl); } hui = document.querySelector('h2').innerHTML; //第几回 let pageNum = document.querySelector('#page').innerHTML; // 第几页 let ext = imgUrl.split('/').pop(); ext = ext.substr(ext.indexOf('.')); //取出后缀名 ext = ext.split('?cid')[0].split('?')[0]; let fullFileName = (comicName + '_' + hui + '_第' + pageNum + '页').substr(0, 200).replace(safe_fileName_rule, '') + ext; //设置文件名 后缀名都改为jpg let nowPageNo; nowPageNo = parseInt(document.querySelector('#pageSelect').value); // 现在的页码 outputE.innerHTML = '正在下载 ' + hui + '第' + nowPageNo + '页 点击可设置停止。'; GM_xmlhttpRequest({ method: 'GET', url: imgUrl, headers: { referer: window.location.href.split(splitString)[0] }, responseType: 'blob', onload: function (xhr) { xhr.response.type = 'image/jpeg'; let blobURL = window.URL.createObjectURL(xhr.response); down_a.href = blobURL; down_a.download = fullFileName; down_a.click(); window.URL.revokeObjectURL(blobURL); setTimeout(() => { // 在测试时,发现哦漫画的页面加载太快,导致很多下载的图片来不及保存,所以加上延时。 if (nowPageNo === pageTotal) { //如果已经最后一页 document.querySelector('.nextC').click(); // 点击下一章 let t = setInterval(() => { if (document.querySelector('#pb')) { //如果出现提示框,则认为没有下一章了 clearInterval(t); userStop = true; setDownloadStatus(false); alert('已经到达最后一页,下载完毕!'); return false; } }, 500); } else { //如果还有下一页 document.querySelector('#next').click(); // 点击下一页按钮 } }, timer_dealy); } }); } // 点击下载按钮时执行 document.querySelector('#startDownload').addEventListener('click', () => { userStop = false; addOutput(); setDownloadStatus(true); // 每次下载时初始化 readyDownload(); // 点击下载按钮时,首先下载当前页 if (isMHG) { window.addEventListener('hashchange', () => { // 这里只在漫画柜生效,因为漫画柜加载下一页是改变hash的。哦漫画没有hash而且需要重新加载页面 readyDownload(); }); } function readyDownload () { window.stop(); if (userStop) { return false; } GMDownload(); } }); // 是否自动继续下载 if (sessionStorage.getItem('continueDown') !== null) { document.querySelector('#startDownload').click(); // 模拟点击,自动继续下载 }