怠惰小说下载器

通用网站内容抓取工具,可批量抓取任意站点的小说、论坛内容等并保存为TXT文档

当前为 2022-03-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name DownloadAllContent
  3. // @name:zh-CN 怠惰小说下载器
  4. // @name:zh-TW 怠惰小説下載器
  5. // @name:ja 怠惰者小説ダウンロードツール
  6. // @namespace hoothin
  7. // @version 2.7.3.2
  8. // @description Fetch and download main content on current page, provide special support for chinese novel
  9. // @description:zh-CN 通用网站内容抓取工具,可批量抓取任意站点的小说、论坛内容等并保存为TXT文档
  10. // @description:zh-TW 通用網站內容抓取工具,可批量抓取任意站點的小說、論壇內容等並保存為TXT文檔
  11. // @description:ja ユニバーサルサイトコンテンツクロールツール、クロール、フォーラム内容など
  12. // @author hoothin
  13. // @include *
  14. // @grant GM_xmlhttpRequest
  15. // @grant GM_registerMenuCommand
  16. // @grant GM_setValue
  17. // @grant GM_getValue
  18. // @grant GM_download
  19. // @grant unsafeWindow
  20. // @require https://cdn.jsdelivr.net/npm/file-saver@2.0.5/dist/FileSaver.min.js
  21. // @license MIT License
  22. // @compatible chrome
  23. // @compatible firefox
  24. // @compatible opera 未测试
  25. // @compatible safari 未测试
  26. // @contributionURL https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=rixixi@sina.com&item_name=Greasy+Fork+donation
  27. // @contributionAmount 1
  28. // ==/UserScript==
  29.  
  30. (function() {
  31. 'use strict';
  32. var indexReg=/PART\b|^Prologue|Chapter\s*[\-_]?\d+|分卷|^序$|^序\s*言|^序\s*章|^前\s*言|^附\s*[录錄]|^引\s*[言子]|^摘\s*要|^[楔契]\s*子|^后\s*记|^後\s*記|^附\s*言|^结\s*语|^結\s*語|^尾\s*[声聲]|^最終話|^最终话|^番\s*外|^\d+\s*\D*[^\d#\.]$|^[第(]?[\d〇零一二三四五六七八九十百千万萬-]+\s*[、)章节節回卷折篇幕集话話]/i;
  33. var innerNextPage=/下一[页頁张張]|next\s*page|次のページ/i;
  34. var lang = navigator.appName=="Netscape"?navigator.language:navigator.userLanguage;
  35. var _GM_download=(typeof GM_download=='undefined')?saveAs:(blob,name)=>{if(blob.size>15*1024*1024)saveAs(blob,name);else GM_download(window.URL.createObjectURL(blob),name)};
  36. var i18n={};
  37. var rCats=[];
  38. var processFunc;
  39. switch (lang){
  40. case "zh-CN":
  41. case "zh-SG":
  42. i18n={
  43. fetch:"开始下载小说【Ctrl+F9】",
  44. info:"本文是使用怠惰小说下载器(DownloadAllContent)下载的",
  45. error:"该段内容获取失败",
  46. downloading:"已下载完成 %s 段,剩余 %s 段<br>正在下载 %s",
  47. complete:"已全部下载完成,共 %s 段",
  48. del:"设置文本干扰码的CSS选择器",
  49. custom:"自定义下载",
  50. customInfo:"输入网址或者章节CSS选择器",
  51. reSort:"按标题名重新排序",
  52. reSortUrl:"按网址重新排序",
  53. setting:"选项设置",
  54. abort:"跳过此章",
  55. save:"临时保存",
  56. downThreadNum:"设置同时下载的线程数"
  57. };
  58. break;
  59. case "zh-TW":
  60. case "zh-HK":
  61. i18n={
  62. fetch:"開始下載小說【Ctrl+F9】",
  63. info:"本文是使用怠惰小說下載器(DownloadAllContent)下載的",
  64. error:"該段內容獲取失敗",
  65. downloading:"已下載完成 %s 段,剩餘 %s 段<br>正在下載 %s",
  66. complete:"已全部下載完成,共 %s 段",
  67. del:"設置文本干擾碼的CSS選擇器",
  68. custom:"自定義下載",
  69. customInfo:"輸入網址或者章節CSS選擇器",
  70. reSort:"按標題名重新排序",
  71. reSortUrl:"按網址重新排序",
  72. setting:"選項設置",
  73. abort:"跳過此章",
  74. save:"保存當前",
  75. downThreadNum:"設置同時下載的綫程數"
  76. };
  77. break;
  78. default:
  79. i18n={
  80. fetch:"Download [Ctrl+F9]",
  81. info:"The TXT is downloaded by 'DownloadAllContent'",
  82. error:"Failed in downloading current chapter",
  83. downloading:"%s pages are downloaded, there are still %s pages left<br>Downloading %s ......",
  84. complete:"Completed! Get %s pages in total",
  85. del:"Set css selectors for ignore",
  86. custom:"Custom to download",
  87. customInfo:"Input urls OR sss selectors for chapter links",
  88. reSort:"ReSort by title",
  89. reSortUrl:"Resort by URLs",
  90. setting:"Open Setting",
  91. abort:"Abort",
  92. save:"Save",
  93. downThreadNum:"Set threadNum for download"
  94. };
  95. break;
  96. }
  97. var firefox=navigator.userAgent.toLowerCase().indexOf('firefox')!=-1,curRequests=[];
  98. var rocketContent,txtDownContent,txtDownWords,txtDownQuit,txtDownDivInited=false;
  99.  
  100. function initTxtDownDiv(){
  101. if(txtDownDivInited)return;
  102. txtDownDivInited=true;
  103. rocketContent=document.createElement("div");
  104. document.body.appendChild(rocketContent);
  105. rocketContent.outerHTML=`
  106. <div id="txtDownContent">
  107. <div style="font-size:16px;color:#333333;width:360px;height:110px;position:fixed;left:50%;top:50%;margin-top:-25px;margin-left:-150px;z-index:100000;background-color:#ffffff;border:1px solid #afb3b6;border-radius:10px;opacity:0.95;filter:alpha(opacity=95);box-shadow:5px 5px 20px 0px #000;">
  108. <div id="txtDownWords" style="position:absolute;width:275px;max-height: 90%;border: 1px solid #f3f1f1;padding: 8px;border-radius: 10px;overflow: auto;">
  109. Downloading......
  110. </div>
  111. <div id="txtDownQuit" style="width:36px;height:28px;border-radius:10px;position:absolute;right:2px;top:2px;cursor: pointer;background-color:#ff5a5a;">
  112. <span style="height:28px;line-height:28px;display:block;color:#FFF;text-align:center;font-size:20px;">╳</span>
  113. </div>
  114. <div style="position:absolute;right:0px;bottom:2px;cursor: pointer;max-width:85px">
  115. <button id="abortRequest" style="background: #008aff;border: 0;padding: 5px;border-radius: 10px;color: white;float: right;margin: 1px;height: 25px;display:none;line-height: 20px;">${getI18n('abort')}</button>
  116. <button id="tempSaveTxt" style="background: #008aff;border: 0;padding: 5px;border-radius: 10px;color: white;float: right;margin: 1px;height: 25px;line-height: 20px;">${getI18n('save')}</button>
  117. </div>
  118. </div>
  119. </div>`;
  120. txtDownContent=document.querySelector("#txtDownContent");
  121. txtDownWords=document.querySelector("#txtDownWords");
  122. txtDownQuit=document.querySelector("#txtDownQuit");
  123. txtDownQuit.onclick=function(){
  124. txtDownContent.style.display="none";
  125. txtDownContent.parentNode.removeChild(txtDownContent);
  126. };
  127. initTempSave();
  128. }
  129.  
  130. function initTempSave(){
  131. var tempSavebtn = document.getElementById('tempSaveTxt');
  132. var abortbtn = document.getElementById('abortRequest');
  133. tempSavebtn.onclick = function(){
  134. var blob = new Blob([i18n.info+"\r\n\r\n"+document.title+"\r\n\r\n"+rCats.join("\r\n\r\n")], {type: "text/plain;charset=utf-8"});
  135. _GM_download(blob, document.title+".txt");
  136. }
  137. abortbtn.onclick = function(){
  138. let curRequest = curRequests.pop();
  139. if(curRequest)curRequest[1].abort();
  140. }
  141. }
  142.  
  143. function indexDownload(aEles){
  144. if(aEles.length<1)return;
  145. initTxtDownDiv();
  146. if(GM_getValue("contentSort")){
  147. aEles.sort(function(a,b){
  148. return parseInt(a.innerText.replace(/[^0-9]/ig,"")) - parseInt(b.innerText.replace(/[^0-9]/ig,""));
  149. });
  150. }
  151. if(GM_getValue("contentSortUrl")){
  152. aEles.sort(function(a,b){
  153. return parseInt(a.href.replace(/[^0-9]/ig,"")) - parseInt(b.href.replace(/[^0-9]/ig,""));
  154. });
  155. }
  156. rCats=[];
  157. var insertSigns=[];
  158. // var j=0,rCats=[];
  159. var downIndex=0,downNum=0,downOnce=function(){
  160. if(downNum>=aEles.length)return;
  161. let curIndex=downIndex;
  162. let aTag=aEles[curIndex];
  163. let request=(aTag, curIndex)=>{
  164. let tryTimes=0;
  165. let requestBody={
  166. method: 'GET',
  167. url: aTag.href,
  168. headers:{referer:aTag.href},
  169. timeout:15000,
  170. overrideMimeType:"text/html;charset="+document.charset,
  171. onload: function(result) {
  172. var doc = getDocEle(result.responseText);
  173. let nextPage=checkNextPage(doc);
  174. if(nextPage){
  175. var inArr=false;
  176. for(var ai=0;ai<aEles.length;ai++){
  177. if(aEles[ai].href==nextPage.href){
  178. inArr=true;
  179. break;
  180. }
  181. }
  182. if(!inArr){
  183. nextPage.innerText=aTag.innerText+"\t>>";
  184. aEles.push(nextPage);
  185. let targetIndex = curIndex;
  186. for(let a=0;a<insertSigns.length;a++){
  187. let signs=insertSigns[a],breakSign=false;
  188. if(signs){
  189. for(let b=0;b<signs.length;b++){
  190. let sign=signs[b];
  191. if(sign==curIndex){
  192. targetIndex=a;
  193. breakSign=true;
  194. break;
  195. }
  196. }
  197. }
  198. if(breakSign)break;
  199. }
  200. let insertSign = insertSigns[targetIndex];
  201. if(!insertSign)insertSigns[targetIndex] = [];
  202. insertSigns[targetIndex].push(aEles.length-1);
  203. }
  204. }
  205. downIndex++;
  206. downNum++;
  207. processDoc(curIndex, aTag, doc);
  208. let request=downOnce();
  209. if(request)curRequests.push(request);
  210. },
  211. onerror: function(e) {
  212. console.warn("error:");
  213. console.log(e);
  214. downIndex++;
  215. downNum++;
  216. processDoc(curIndex, aTag, null, ' : NETWORK ERROR '+(e.response||e.responseText));
  217. let request=downOnce();
  218. if(request)curRequests.push(request);
  219. },
  220. ontimeout: function(e) {
  221. console.warn("timeout: times="+tryTimes+" url="+aTag.href);
  222. //console.log(e);
  223. if(++tryTimes<3){
  224. return GM_xmlhttpRequest(requestBody);
  225. }
  226. downIndex++;
  227. downNum++;
  228. processDoc(curIndex, aTag, null, ' : TIMEOUT '+aTag.href);
  229. let request=downOnce();
  230. if(request)curRequests.push(request);
  231. }
  232. };
  233. return [curIndex,GM_xmlhttpRequest(requestBody)];
  234. }
  235. if(!aTag){
  236. let waitAtagReadyInterval=setInterval(function(){
  237. if(downNum>=aEles.length)clearInterval(waitAtagReadyInterval);
  238. aTag=aEles[curIndex];
  239. if(aTag){
  240. clearInterval(waitAtagReadyInterval);
  241. request(aTag, curIndex);
  242. }
  243. },1000);
  244. return null;
  245. }
  246. return request(aTag, curIndex);
  247. };
  248. function getDocEle(str){
  249. var doc = null;
  250. try {
  251. doc = document.implementation.createHTMLDocument('');
  252. doc.documentElement.innerHTML = str;
  253. }
  254. catch (e) {
  255. console.log('parse error');
  256. }
  257. return doc;
  258. }
  259. function sortInnerPage(){
  260. var pageArrs=[],maxIndex=0,i,j;
  261. for(i=0;i<insertSigns.length;i++){
  262. var signs=insertSigns[i];
  263. if(signs){
  264. for(j=0;j<signs.length;j++){
  265. var sign=signs[j];
  266. var cat=rCats[sign];
  267. rCats[sign]=null;
  268. if(!pageArrs[i])pageArrs[i]=[];
  269. pageArrs[i].push(cat);
  270. }
  271. }
  272. }
  273. for(i=pageArrs.length-1;i>=0;i--){
  274. let pageArr=pageArrs[i];
  275. if(pageArr){
  276. for(j=pageArr.length-1;j>=0;j--){
  277. rCats.splice(i+1, 0, pageArr[j]);
  278. }
  279. }
  280. }
  281. rCats = rCats.filter(function(e){return e!=null});
  282. }
  283. function processDoc(i, aTag, doc, cause){
  284. curRequests = curRequests.filter(function(e){return e[0]!=i});
  285. rCats[i]=(aTag.innerText.trim()+"\r\n"+getPageContent(doc) + (cause||''));
  286. txtDownContent.style.display="block";
  287. txtDownWords.innerHTML=getI18n("downloading",[downNum,(aEles.length-downNum),aTag.innerText]);
  288. if(downNum==aEles.length){
  289. txtDownWords.innerHTML=getI18n("complete",[downNum]);
  290. sortInnerPage();
  291. var blob = new Blob([i18n.info+"\r\n\r\n"+document.title+"\r\n\r\n"+rCats.join("\r\n\r\n")], {type: "text/plain;charset=utf-8"});
  292. _GM_download(blob, document.title+".txt");
  293. }
  294. }
  295. var downThreadNum = parseInt(GM_getValue("downThreadNum"));
  296. downThreadNum=downThreadNum>0?downThreadNum:20;
  297. for(var i=0;i<downThreadNum;i++){
  298. let request=downOnce();
  299. if(request)curRequests.push(request);
  300. if(downIndex>=aEles.length-1 || downIndex>=downThreadNum-1)break;
  301. else downIndex++;
  302. }
  303.  
  304. /*for(let i=0;i<aEles.length;i++){
  305. let aTag=aEles[i];
  306. GM_xmlhttpRequest({
  307. method: 'GET',
  308. url: aTag.href,
  309. overrideMimeType:"text/html;charset="+document.charset,
  310. onload: function(result) {
  311. var doc = getDocEle(result.responseText);
  312. processDoc(i, aTag, doc);
  313. }
  314. });
  315. }*/
  316. }
  317.  
  318. function checkNextPage(doc){
  319. let aTags=doc.querySelectorAll("a"),nextPage=null;
  320. for(var i=0;i<aTags.length;i++){
  321. let aTag=aTags[i];
  322. if(innerNextPage.test(aTag.innerText) && aTag.href.indexOf("javascript")==-1){
  323. nextPage=aTag;
  324. break;
  325. }
  326. }
  327. return nextPage;
  328. }
  329.  
  330. function getPageContent(doc){
  331. if(!doc)return i18n.error;
  332. if(processFunc){
  333. return processFunc(doc);
  334. }
  335. if(doc.defaultView){
  336. [].forEach.call(doc.querySelectorAll("span,div,ul"),function(item){
  337. var thisStyle=doc.defaultView.getComputedStyle(item);
  338. if(thisStyle && (thisStyle.display=="none" || (item.tagName=="SPAN" && thisStyle.fontSize=="0px")))
  339. item.innerHTML="";
  340. });
  341. }
  342. var i,j,k,rStr="",pageData=(doc.body?doc.body:doc).cloneNode(true),delList=[];
  343. pageData.innerHTML=pageData.innerHTML.replace(/\<\!\-\-((.|[\n|\r|\r\n])*?)\-\-\>/g,"");
  344. [].forEach.call(pageData.querySelectorAll("font.jammer"),function(item){
  345. item.innerHTML="";
  346. });
  347. var selectors=GM_getValue("selectors");
  348. if(selectors){
  349. [].forEach.call(pageData.querySelectorAll(selectors),function(item){
  350. item.innerHTML="";
  351. });
  352. }
  353. [].forEach.call(pageData.querySelectorAll("script,style,link,img,noscript,iframe"),function(item){delList.push(item);});
  354. [].forEach.call(delList,function(item){item.innerHTML="";});
  355. var largestContent,contents=pageData.querySelectorAll("span,div,article,p,td"),largestNum=0;
  356. for(i=0;i<contents.length;i++){
  357. let content=contents[i],hasText=false,allSingle=true,item,curNum=0;
  358. for(j=content.childNodes.length-1;j>=0;j--){
  359. item=content.childNodes[j];
  360. if(item.nodeType==3){
  361. if(/^\s*$/.test(item.data))
  362. item.innerHTML="";
  363. else hasText=true;
  364. }else if(/^(I|A|STRONG|B|FONT|P|DL|DD|H\d)$/.test(item.tagName))hasText=true;
  365. }
  366. for(j=content.childNodes.length-1;j>=0;j--){
  367. item=content.childNodes[j];
  368. if(item.nodeType==1 && !/^(I|A|STRONG|B|FONT|BR)$/.test(item.tagName) && /^[\s\-\_\?\>\|]*$/.test(item.innerHTML))
  369. item.innerHTML="";
  370. }
  371. if(content.childNodes.length>1){
  372. for(j=0;j<content.childNodes.length;j++){
  373. item=content.childNodes[j];
  374. if(item.nodeType==1){
  375. for(k=0;k<item.childNodes.length;k++){
  376. var childNode=item.childNodes[k];
  377. if(childNode.nodeType!=3 && !/^(I|A|STRONG|B|FONT|BR)$/.test(childNode.tagName)){
  378. allSingle=false;
  379. break;
  380. }
  381. }
  382. if(!allSingle)break;
  383. }
  384. }
  385. }else{
  386. allSingle=false;
  387. }
  388. if(allSingle){
  389. curNum=(firefox?content.textContent.length:content.innerText.length);
  390. }else {
  391. if(!hasText)continue;
  392. if(pageData==document && content.offsetWidth<=0 && content.offsetHeight<=0)
  393. continue;
  394. [].forEach.call(content.childNodes,function(item){
  395. if(item.nodeType==3)curNum+=item.data.length;
  396. else if(/^(I|A|STRONG|B|FONT|P|DL|DD|H\d)$/.test(item.tagName))curNum+=(firefox?item.textContent.length:item.innerText.length);
  397. });
  398. }
  399. if(curNum>largestNum){
  400. largestNum=curNum;
  401. largestContent=content;
  402. }
  403. }
  404. if(!largestContent)return i18n.error+" : NO TEXT CONTENT";
  405. var childlist=pageData.querySelectorAll(largestContent.tagName);//+(largestContent.className?"."+largestContent.className.replace(/(^\s*)|(\s*$)/g, '').replace(/\s+/g, '.'):""));
  406. function getRightStr(ele, noTextEnable){
  407. let childNodes=ele.childNodes,cStr="\r\n",hasText=false;
  408. for(let j=0;j<childNodes.length;j++){
  409. let childNode=childNodes[j];
  410. if(childNode.nodeType==3 && childNode.data && !/^[\s\-\_\?\>\|]*$/.test(childNode.data))hasText=true;
  411. if(childNode.innerHTML){
  412. childNode.innerHTML=childNode.innerHTML.replace(/\<\s*br\s*\>/gi,"\r\n").replace(/\n+/gi,"\n").replace(/\r+/gi,"\r");
  413. }
  414. if(childNode.textContent){
  415. cStr+=childNode.textContent.replace(/ +/g," ").replace(/([^\r]|^)\n([^\r]|$)/gi,"$1\r\n$2");
  416. }
  417. if(childNode.nodeType!=3 && !/^(I|A|STRONG|B|FONT)$/.test(childNode.tagName))cStr+="\r\n";
  418. }
  419. if(hasText || noTextEnable || ele==largestContent)rStr+=cStr+"\r\n";
  420. }
  421. for(i=0;i<childlist.length;i++){
  422. var child=childlist[i];
  423. if(getDepth(child)==getDepth(largestContent)){
  424. if((!largestContent.className && child.className) || (largestContent.className && !child.className) || (largestContent.className && child.className && largestContent.className != child.className))continue;
  425. if((largestContent.className && largestContent.className==child.className)||largestContent.parentNode ==child.parentNode){
  426. getRightStr(child, true);
  427. }else {
  428. getRightStr(child, false);
  429. }
  430. }
  431. }
  432. return rStr.replace(/[\n\r]+/g,"\n\r");
  433. }
  434.  
  435. function getI18n(key, args){
  436. var resultStr=i18n[key];
  437. if(args && args.length>0){
  438. args.forEach(function(item){
  439. resultStr=resultStr.replace(/%s/,item);
  440. });
  441. }
  442. return resultStr;
  443. }
  444.  
  445. function getDepth(dom){
  446. var pa=dom,i=0;
  447. while(pa.parentNode){
  448. pa=pa.parentNode;
  449. i++;
  450. }
  451. return i;
  452. }
  453.  
  454. function fetch(forceSingle){
  455. forceSingle=forceSingle===true;
  456. processFunc=null;
  457. var aEles=document.querySelectorAll("a"),list=[];
  458. for(var i=0;i<aEles.length;i++){
  459. var aEle=aEles[i],has=false;
  460. if((!aEle.href || aEle.href.indexOf("javascript")!=-1) && aEle.dataset.href){
  461. aEle.href=aEle.dataset.href;
  462. }
  463. for(var j=0;j<list.length;j++){
  464. if(list[j].href==aEle.href){
  465. aEle=list[j];
  466. list.splice(j,1);
  467. list.push(aEle);
  468. has=true;
  469. break;
  470. }
  471. }
  472. if(!has && aEle.href && /^http/i.test(aEle.href) && ((aEle.innerText.trim()!="" && indexReg.test(aEle.innerText.trim())) || /chapter[\-_]?\d/.test(aEle.href))){
  473. list.push(aEle);
  474. }
  475. }
  476. if(list.length>2 && !forceSingle){
  477. indexDownload(list);
  478. }else{
  479. var blob = new Blob([i18n.info+"\r\n\r\n"+document.title+"\r\n\r\n"+getPageContent(document)], {type: "text/plain;charset=utf-8"});
  480. _GM_download(blob, document.title+".txt");
  481. }
  482. }
  483.  
  484. document.addEventListener("keydown", function(e) {
  485. if(e.keyCode == 120 && e.ctrlKey) {
  486. fetch(e.shiftKey);
  487. }
  488. });
  489. function setDel(){
  490. var selValue=GM_getValue("selectors");
  491. var selectors=prompt(i18n.del,selValue?selValue:"");
  492. GM_setValue("selectors",selectors);
  493. selValue=GM_getValue("downThreadNum");
  494. var downThreadNum=prompt(i18n.downThreadNum,selValue?selValue:"20");
  495. GM_setValue("downThreadNum",downThreadNum);
  496. GM_setValue("contentSort",window.confirm(i18n.reSort));
  497. GM_setValue("contentSortUrl",window.confirm(i18n.reSortUrl));
  498. }
  499. function customDown(){
  500. processFunc=null;
  501. var customRules=GM_getValue("DACrules_"+document.domain);
  502. var urls=window.prompt(i18n.customInfo,customRules?customRules:"https://xxx.xxx/book-[20-99].html, https://xxx.xxx/book-[01-10].html");
  503. if(urls){
  504. GM_setValue("DACrules_"+document.domain, urls);
  505. var processEles=[];
  506. if(/^http|^ftp/.test(urls)){
  507. [].forEach.call(urls.split(","),function(i){
  508. var curEle;
  509. var varNum=/\[\d+\-\d+\]/.exec(i);
  510. if(varNum){
  511. varNum=varNum[0].trim();
  512. }else{
  513. curEle=document.createElement("a");
  514. curEle.href=i;
  515. processEles.push(curEle);
  516. return;
  517. }
  518. var num1=/\[(\d+)/.exec(varNum)[1].trim();
  519. var num2=/(\d+)\]/.exec(varNum)[1].trim();
  520. var num1Int=parseInt(num1);
  521. var num2Int=parseInt(num2);
  522. var numLen=num1.length;
  523. var needAdd=num1.charAt(0)=="0";
  524. if(num1Int>=num2Int)return;
  525. for(var j=num1Int;j<=num2Int;j++){
  526. var urlIndex=j.toString();
  527. if(needAdd){
  528. while(urlIndex.length<numLen)urlIndex="0"+urlIndex;
  529. }
  530. var curUrl=i.replace(/\[\d+\-\d+\]/,urlIndex).trim();
  531. curEle=document.createElement("a");
  532. curEle.href=curUrl;
  533. processEles.push(curEle);
  534. curEle.innerText=processEles.length.toString();
  535. }
  536. });
  537. }else{
  538. let urlsArr=urls.split("@@"),eles=[];
  539. let urlSel=urlsArr[0].split(">>");
  540. try{
  541. eles=document.querySelectorAll(urlSel[0]);
  542. }catch(e){}
  543. if(eles.length==0){
  544. eles=[];
  545. var eleTxts=urlsArr[0].split(/(?<=[^\\])[,,]/),exmpEles=[],excludeTxts={};
  546. [].forEach.call(document.querySelectorAll("a"),function(item){
  547. eleTxts.forEach(txt=>{
  548. var txtArr=txt.split("!");
  549. if(item.innerText.indexOf(txtArr[0])!=-1){
  550. exmpEles.push(item);
  551. excludeTxts[item]=txtArr.splice(1);
  552. }
  553. });
  554. })
  555. exmpEles.forEach(e=>{
  556. var cssSelStr="a",pa=e.parentNode,excludeTxt=excludeTxts[e];
  557. if(e.className)cssSelStr+="."+CSS.escape(e.className);
  558. while(pa && pa.nodeName!="BODY"){
  559. cssSelStr=pa.nodeName+">"+cssSelStr;
  560. pa=pa.parentNode;
  561. }
  562. [].forEach.call(document.querySelectorAll(cssSelStr),function(item){
  563. var isExclude=false;
  564. for(var t in excludeTxt){
  565. if(item.innerText.indexOf(excludeTxt[t])!=-1){
  566. isExclude=true;
  567. break;
  568. }
  569. }
  570. if(!isExclude && eles.indexOf(item)==-1){
  571. eles.push(item);
  572. }
  573. });
  574. });
  575. }
  576. [].forEach.call(eles,function(item){
  577. if(urlSel[1]){
  578. item=Function("item",urlSel[1])(item);
  579. if(!item || !item.href)return;
  580. if(!item.tagName || item.tagName!="A"){
  581. let href=item.href;
  582. let innerText=item.innerText;
  583. item=document.createElement("a");
  584. item.href=href;
  585. item.innerText=innerText;
  586. }
  587. }
  588. let has=false;
  589. for(var j=0;j<processEles.length;j++){
  590. if(processEles[j].href==item.href){
  591. processEles.splice(j,1);
  592. processEles.push(item);
  593. has=true;
  594. break;
  595. }
  596. }
  597. if((!item.href || item.href.indexOf("javascript")!=-1) && item.dataset.href){
  598. item.href=item.dataset.href;
  599. }
  600. if(!has && item.href && /^http/i.test(item.href)){
  601. processEles.push(item.cloneNode(1));
  602. }
  603. });
  604. if(urlsArr[1]){
  605. processEles.forEach(ele=>{
  606. ele.href=ele.href.replace(new RegExp(urlsArr[1]), urlsArr[2]);
  607. });
  608. }
  609. if(urlsArr[3]){
  610. processFunc=data=>{
  611. if(urlsArr[3].indexOf("return ")==-1){
  612. return eval(urlsArr[3])
  613. }else{
  614. return Function("data",urlsArr[3])(data);
  615. }
  616. };
  617. }else{
  618. var win=(typeof unsafeWindow=='undefined'? window : unsafeWindow);
  619. if(win.dacProcess){
  620. processFunc=win.dacProcess;
  621. }
  622. }
  623. }
  624. indexDownload(processEles);
  625. }
  626. }
  627. GM_registerMenuCommand(i18n.fetch, fetch);
  628. GM_registerMenuCommand(i18n.custom, customDown);
  629. GM_registerMenuCommand(i18n.setting, setDel);
  630. })();