├── README.MD └── src └── netdisk_download_helper.user.js /README.MD: -------------------------------------------------------------------------------- 1 | # 网盘提取工具 2 | 3 | 尽可能在支持的网盘自动输入提取码,省去下载的烦恼。 4 | 5 | 目前支持的网盘: 6 | 7 | * 百度云盘 8 | * 蓝奏云 9 | * 天翼云 10 | 11 | 致力于提供更简便的网盘分享体验。 12 | 13 | **源码@Github**: [https://github.com/iccfish/netdisk-helper](https://github.com/iccfish/netdisk-helper) 14 | 15 | **官方博客**:[http://blog.fishlee.net/?p=3473](http://blog.fishlee.net/?p=3473) 16 | 17 | ## 安装说明 18 | 19 | * 在 Firefox 上,您需要安装[**GreaseMonkey**](https://addons.mozilla.org/zh-CN/firefox/addon/greasemonkey/)或[**TamperMonkey**](https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/)扩展 20 | * 在 Chrome 上,您需要安装[**TamperMonkey**](https://chrome.google.com/webstore/detail/dhdgffkkebhmkfjojejmpbldmpobfkfo) 扩展 21 | 22 | 在浏览器准备就绪后,在[脚本发布页面](https://greasyfork.org/zh-CN/scripts/18733-%E7%BD%91%E7%9B%98%E6%8F%90%E5%8F%96%E5%B7%A5%E5%85%B7)安装即可。 23 | 24 | ## 更新记录 25 | 26 | ### 2020-7-3 `3.3` 27 | 28 | * 优化对蓝奏云的支持 29 | 30 | ### 2018-12-20 `3.2` 31 | 32 | * 增加了对189.cn的支持 33 | 34 | ### 2018-05-22 `3.1` 35 | 36 | * 完善了对蓝奏云的支持 37 | * 代码进行了重构 38 | 39 | ### 2018-04-12 `3.0` 40 | 41 | * 增加了对蓝奏云的提取码支持 42 | 43 | ### 2018-04-08 `2.8` 44 | 45 | * 合并了 @Heavensward 的提交,提供了对最新版百度网盘分享链接的支持 46 | 47 | ### 2017-11-09 `2.7` 48 | 49 | * 修改对于百度云盘的支持 50 | 51 | ### 2017-06-07 `2.6` 52 | 53 | * 修正对于企业百度云链接识别错误的 BUG 54 | * 修正对于链接中自带锚点标记时重复加锚点的 BUG 55 | 56 | ### 2017-05-18 `2.5` 57 | 58 | * 移除对 360 的支持 59 | * 改善对最新版本 Chrome 的支持 60 | 61 | ### 2016-05-05 `2.4` 62 | 63 | * 移除对新浪微盘的支持(反正丫快倒闭了 o(╯□╰)o) 64 | * 部分代码重构 65 | 66 | ### 2016-05-05 `2.3` 67 | 68 | * 增加文本匹配模式,自动识别非链接的文本并转换为超链接 69 | -------------------------------------------------------------------------------- /src/netdisk_download_helper.user.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name 网盘提取工具 3 | // @namespace http://www.fishlee.net/ 4 | // @version 3.3 5 | // @description 尽可能在支持的网盘自动输入提取码,省去下载的烦恼。 6 | // @author 木鱼(iFish) 7 | // @match *://*/* 8 | // @grant unsafeWindow 9 | // @icon https://ssl-static.fishlee.net/resources/emot/xr/22.gif 10 | // ==/UserScript== 11 | 12 | (function(window, self, unsafeWindow) { 13 | 'use strict'; 14 | let timeStart = new Date().getTime(); 15 | let location = self.location; 16 | let host = location.host; 17 | let path = location.pathname; 18 | let code, input; 19 | let getCode = function(rule) { 20 | code = location.hash.slice(1, 5); 21 | if ((rule || /([a-z\d]{4})/i.exec(code))) { 22 | code = RegExp.$1; 23 | } else code = null; 24 | return code; 25 | }; 26 | if (/(pan|e?yun)\.baidu\.com/.test(host)) { 27 | //百度云盘 28 | if (path.indexOf("/share/") !== -1 && document.querySelector('form[name="accessForm"]') && getCode()) { 29 | let target = document.querySelector('.pickpw input'); 30 | if (!target) 31 | return; 32 | 33 | target.value = code; 34 | unsafeWindow.document.querySelector('form[name="accessForm"]').onsubmit(); 35 | } 36 | } else if (/\.lanzou[sx]?\.com/.test(host) && getCode()) { 37 | let target = document.querySelector('#pwd'); 38 | if (!target) 39 | return; 40 | 41 | target.value = code; 42 | let btn = unsafeWindow.document.querySelector('#sub') || unsafeWindow.document.querySelector('.passwddiv-btn'); 43 | 44 | btn && btn.dispatchEvent(new UIEvent('click')); 45 | } else if (/cloud.189.cn/.test(host) && getCode()) { 46 | let target = document.getElementById('code_txt'); 47 | if (!target) 48 | return; 49 | 50 | target.value = code; 51 | 52 | let nameLabel = document.querySelector('.shareDate'); 53 | let delayFunc = () => { 54 | if (!nameLabel.innerText) { 55 | console.log('delay 500ms due to page load not complete.'); 56 | setTimeout(delayFunc, 500); 57 | } else { 58 | unsafeWindow.$(target.nextElementSibling).click(); 59 | } 60 | }; 61 | setTimeout(delayFunc, 500); 62 | } else { 63 | //其它网站,检测链接 64 | Array.prototype.slice.call(document.querySelectorAll("a[href*='pan.baidu.com'], a[href*='lanzou.com'], a[href*='lanzous.com'], a[href*='lanzoux.com']")).forEach(function(link) { 65 | let txt = link.nextSibling && link.nextSibling.nodeValue; 66 | let linkcode = /码.*?([a-z\d]{4})/i.exec(txt) && RegExp.$1; 67 | if (!linkcode) { 68 | txt = link.parentNode.innerText; 69 | linkcode = /码.*?([a-z\d]{4})/i.exec(txt) && RegExp.$1; 70 | } 71 | if (linkcode) { 72 | let href = link.getAttribute("href"); 73 | link.setAttribute("href", href + "#" + linkcode); 74 | } 75 | }); 76 | } 77 | let timeEnd = new Date().getTime(); 78 | console.log("[网盘提取工具] 链接处理完成,耗时:" + (timeEnd - timeStart) + "毫秒. 处理模式:DOM处理"); 79 | })(window, window.self, unsafeWindow); 80 | (function() { 81 | 'use strict'; 82 | //consts... 83 | let CODE_RULE_COMMON = /^([a-z\d]{4})$/i; 84 | let MAX_SEARCH_CODE_RANGE = 5; 85 | //functions... 86 | let textNodesUnder = function(el) { 87 | let n, a = [], 88 | walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false); 89 | while ((n = walk.nextNode())) { 90 | if (n.nodeName === '#text') 91 | a.push(n); 92 | } 93 | return a; 94 | }; 95 | let generalLinkifyText = function(source, eles, index, testReg, validateRule) { 96 | let count = 0, 97 | text = source, 98 | match; 99 | while ((match = testReg.exec(source))) { 100 | count++; 101 | 102 | let url = (match[1] || "http://") + match[2]; 103 | let originalText = (match[1] || "") + match[2]; 104 | let code = match[3] || findCodeFromElements(eles, index, validateRule) || ""; 105 | if (!code) 106 | continue; 107 | console.log("[网盘提取工具] 已处理网盘地址,URL=" + url + ",提取码=" + code + "模式:TEXTNODE"); 108 | //fix double # 109 | url = url.split('#')[0]; 110 | text = text.replace(originalText, "" + url + ''); 111 | } 112 | return { 113 | count, 114 | text 115 | }; 116 | }; 117 | let linkifyTextBlockBaidu = function(...args) { 118 | return generalLinkifyText(...[ 119 | ...args, 120 | /(https?:\/\/)?((?:pan|e?yun)\.baidu\.com\/s\/(?:[a-z\d\-_]+)(?:#[a-z\d-_]*)?)(?:.*?码.*?([a-z\d]+))?/gi, 121 | CODE_RULE_COMMON 122 | ]); 123 | }; 124 | let linkifyTextBlockLanZou = function(...args) { 125 | return generalLinkifyText(...[ 126 | ...args, 127 | /(https?:\/\/)?((?:pan|d|www)\.lanzou[sx]?\.com\/(?:[a-z\d]+))(?:.*?码.*?([a-z\d]+))?/gi, 128 | CODE_RULE_COMMON 129 | ]); 130 | }; 131 | let linkifyTextBlock189cn = function(...args) { 132 | return generalLinkifyText(...[ 133 | ...args, 134 | /(https?:\/\/)?(cloud\.189?\.cn\/t\/(?:[a-z\d]+))(?:.*?码.*?([a-z\d]+))?/gi, 135 | CODE_RULE_COMMON 136 | ]); 137 | } 138 | let findCodeFromElements = function(eles, index, rule) { 139 | for (let i = 0; i < MAX_SEARCH_CODE_RANGE && i < eles.length; i++) { 140 | let txt = eles[i + index].textContent; 141 | let codeReg = /码.*?([a-z\d]+)/gi; 142 | let codeMatch = codeReg.exec(txt) && RegExp.$1; 143 | if (!codeMatch) continue; 144 | let linkTestReg = /(https?:|\.(net|cn|com|gov|cc|me))/gi; 145 | if (linkTestReg.exec(txt) && linkTestReg.lastIndex <= codeReg.lastIndex) { 146 | break; 147 | } 148 | if (rule.test(codeMatch)) return codeMatch; 149 | } 150 | return null; 151 | }; 152 | let linkify = function() { 153 | let eles = textNodesUnder(document.body); 154 | let processor = [ 155 | linkifyTextBlockBaidu, 156 | linkifyTextBlockLanZou, 157 | linkifyTextBlock189cn 158 | ]; 159 | for (let i = 0; i < eles.length; i++) { 160 | let ele = eles[i]; 161 | if (ele.parentNode.tagName == 'a' || !ele.textContent) continue; 162 | 163 | let txt = ele.textContent; 164 | let loopCount = 0; 165 | 166 | for (var action of processor) { 167 | let { 168 | count, 169 | text 170 | } = action(txt, eles, i + 1); 171 | loopCount += count; 172 | txt = text; 173 | } 174 | if (loopCount > 0) { 175 | var span = document.createElement("span"); 176 | span.innerHTML = txt; 177 | ele.parentNode.replaceChild(span, ele); 178 | } 179 | } 180 | }; 181 | let timeStart = new Date().getTime(); 182 | linkify(); 183 | let timeEnd = new Date().getTime(); 184 | console.log("[网盘提取工具] 链接处理完成,耗时:" + (timeEnd - timeStart) + "毫秒. 处理模式:TEXTNODE处理"); 185 | })(); --------------------------------------------------------------------------------