您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
try to take over the world!
// ==UserScript== // @name 文泉学堂即时下载 // @namespace http://tampermonkey.net/ // @version 0.31 // @description try to take over the world! // @author ycf // @match https://*.wqxuetang.com/read/pdf/* // @grant none // @require https://cdn.staticfile.org/blueimp-md5/2.12.0/js/md5.min.js // 基于 https://greasyfork.org/zh-CN/scripts/396025-%E6%96%87%E6%B3%89%E5%AD%A6%E5%A0%82pdf%E4%B8%8B%E8%BD%BD 修改 // ==/UserScript== (function() { var imgBox var name = '' var fuzzyCount = 0 // 连续出现模糊图片计数 var startPage, allPage = 1 var isStart, isBanned = false var pageList = [] var coverMD5, lastMD5 const fuzzyCountLimit = 3 // 连续出现模糊图片的次数达到此值,脚本暂停 const limitNum = [64655, 22471] const limitMD5 = ["aba56eca9b49564cb47bce3f57bd14c2", "d9fff72044ac9a2726972b9dba58aa4e"] // 用于获取书名 const baseURL = `https://${window.location.host}/` if(baseURL.indexOf("www") > -1){window.location.href=window.location.href.replace("www","lib-nuanxin")} const bid = window.location.href.replace(baseURL + "read/pdf/","") const agent = navigator.userAgent const headers = { "headers": { "User-Agent": agent, "Accept": "*/*", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Cache-Control": "max-age=0" }, "referrer": window.location.href, "method": "GET" } Array.prototype.remove = function (val) { const index = this.indexOf(val); if (index > -1) { this.splice(index, 1); } } function sleep (max,min) { const time = !min ? max : Math.floor(Math.random() * (max - min + 1) ) + min; return new Promise((resolve) => setTimeout(resolve, time)); } function imgCheck(c){ if(c.length in limitNum && md5(c) in limitMD5){ return false } return true } function getName(v){ name = v.data.name } function getInfo(url){ const data = fetch(url, headers).then(function(res){ if(res.status >=200 && res.status <300){ return res.json(); }else{ throw new Error(res.statusText) } }) data.then(v=>{getName(v)}) } function downloadImg(content, fileName) { //下载base64图片 var base64ToBlob = function(code) { let parts = code.split(';base64,'); let contentType = parts[0].split(':')[1]; let raw = window.atob(parts[1]); let rawLength = raw.length; let uInt8Array = new Uint8Array(rawLength); for(let i = 0; i < rawLength; ++i) { uInt8Array[i] = raw.charCodeAt(i); } return new Blob([uInt8Array], { type: contentType }); }; let aLink = document.createElement('a'); let blob = base64ToBlob(content); //new Blob([content]); let evt = document.createEvent("HTMLEvents"); evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为 aLink.download = fileName; aLink.href = URL.createObjectURL(blob); aLink.click(); } async function autoScroll(index){ // 自动滚动并下载当前页面图片 if (!isStart){ return } if (pageList.length === 0) { console.log('结束') alert('运行结束') isStart = false return } if (index >= pageList.length){ index = 0 } console.log(`跳转到${pageList[index]}页`) document.documentElement.scrollTop = imgBox[pageList[index]].offsetTop // 跳转到对应页 let src = imgBox[index].firstChild.getAttribute("src") if(!src || src.indexOf("data:image/") === -1){ // 未获取到清晰图片,稍作等待 await sleep(3000,5000) // 等待时间范围,可调整 src = imgBox[pageList[index]].firstChild.getAttribute("src") } if(!src || src.indexOf("width=160") > -1 || !imgCheck(src)){ // 缩略图,暂时跳过 fuzzyCount += 1 if(fuzzyCount >= fuzzyCountLimit){ isStart = false alert(`连续出现 ${fuzzyCount} 次模糊图片,请检查是否需要滑动验证`) return } console.log(`${pageList[index]}页模糊,暂时跳过`) autoScroll(index += 1) }else{ // base64 图片 fuzzyCount = 0 let srcMD5 = md5(src) console.log(`MD5: ${srcMD5}`) if(!coverMD5 && index === 0 && pageList[index] === 1){ // 封面 console.log('记录封面 MD5') coverMD5 = srcMD5 }else{ // 其他页面 if(coverMD5 === srcMD5 || lastMD5 === srcMD5){ // 其他页面出现封面,或和上一张图片一样(解决未从第一页开始下载没有封面数据的情况) isStart = false isBanned = true alert('检测到封面或和上一张图片一样(最后一张下载的可能是封面,注意清理),请刷新或更换IP') return } } lastMD5 = srcMD5 // 记录 MD5 // 下载图片 downloadImg(src, `${bid}_${name}_${pageList[index]}.jpg`) pageList.remove(pageList[index]) autoScroll(index) } } window.onload = function(){ // 获取书名信息 getInfo("https://lib-nuanxin.wqxuetang.com/v1/read/initread?bid="+bid) document.getElementById("pagebox").onclick = function(){ if (!isStart) { // 未运行 if (isBanned){ // 因下载到封面而暂停无法直接继续运行,先排查问题 alert('请刷新页面(最后一张下载的有可能是封面,注意清理)') return } if (!imgBox){ // 首次运行 console.log('初始化...') const numBox = document.getElementsByClassName("page-head-tol")[0].innerHTML imgBox = document.getElementsByClassName("page-img-box") startPage = parseInt(numBox.slice(0, numBox.indexOf("/") - 1)) allPage = imgBox.length - 1 console.log(name + ' 共:' + allPage + '页') // 需要下载的范围 for(let i = startPage; i <= allPage; i++){ pageList.push(i) } console.log(pageList) } isStart = true autoScroll(0) }else{ // 运行中 isStart = false alert('当前页面下载后,将暂停运行') return } } window.onbeforeunload=function(){ if(isStart) { return "leave?"; } } } })();