自动无缝翻页

自动无缝翻页,目前支持:423Down、Apphot、不死鸟、小众软件、异次元软件、AlphaCoders、三国杀论坛、PubMed

当前为 2021-03-31 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name 自动无缝翻页
  3. // @version 1.1.7
  4. // @author X.I.U
  5. // @description 自动无缝翻页,目前支持:423Down、Apphot、不死鸟、小众软件、异次元软件、AlphaCoders、三国杀论坛、PubMed
  6. // @match *://www.423down.com/*
  7. // @exclude *://www.423down.com/*.html
  8. // @match *://apphot.cc/*
  9. // @exclude *://apphot.cc/*.html
  10. // @match *://iao.su/*
  11. // @match *://www.appinn.com/
  12. // @match *://www.appinn.com/*/*/
  13. // @match *://www.appinn.com/?s=*
  14. // @match *://www.iplaysoft.com/*
  15. // @match *://*.alphacoders.com/*
  16. // @match *://club.sanguosha.com/*
  17. // @match *://pubmed.ncbi.nlm.nih.gov/?term=*
  18. // @icon https://i.loli.net/2021/03/07/rdijeYm83pznxWq.png
  19. // @grant GM_xmlhttpRequest
  20. // @grant GM_registerMenuCommand
  21. // @grant GM_openInTab
  22. // @license GPL-3.0 License
  23. // @run-at document-end
  24. // @namespace https://github.com/XIU2/UserScript
  25. // ==/UserScript==
  26.  
  27. (function() {
  28. // 注册(不可用)脚本菜单
  29. GM_registerMenuCommand('反馈 & 欢迎申请支持', function () {window.GM_openInTab('https://github.com/XIU2/UserScript#xiu2userscript', {active: true,insert: true,setParent: true});window.GM_openInTab('https://gf.qytechs.cn/zh-CN/scripts/419215/feedback', {active: true,insert: true,setParent: true});});
  30.  
  31. // 默认 ID 为 0
  32. var curSite = {SiteTypeID: 0};
  33.  
  34. // 自动翻页规则
  35. // type:1 = 脚本实现自动无缝翻页,2 = 网站自带了自动无缝翻页功能,只需要点击下一页按钮即可,这时 nextText 为按钮文本,避免一瞬间加载太多次下一页
  36. // HT_insert:1 = 插入该元素本身的前面;2 = 插入该元素当中,第一个子元素前面;3 = 插入该元素当中,最后一个子元素后面;4 = 插入该元素本身的后面;
  37. // scrollDelta:数值越大,滚动条触发点越靠上(越早开始翻页)
  38. // beforeFunction = 插入前执行函数;afterFunction = 插入后执行函数
  39. let DBSite = {
  40. _423down_postslist: {
  41. SiteTypeID: 1,
  42. pager: {
  43. type: 1,
  44. nextLink: '//div[@class="paging"]//a[contains(text(),"下一页")][@href]',
  45. pageElement: 'css;div.content-wrap ul.excerpt > li',
  46. HT_insert: ['css;div.content-wrap ul.excerpt', 3],
  47. replaceE: 'css;div.paging',
  48. scrollDelta: 1500
  49. }
  50. },
  51. apphot_postslist: {
  52. SiteTypeID: 2,
  53. pager: {
  54. type: 1,
  55. nextLink: '//div[@class="pagination"]//a[contains(text(),"下一页")][@href]',
  56. pageElement: 'css;div.content > article.excerpt',
  57. HT_insert: ['css;div.pagination', 1],
  58. replaceE: 'css;div.pagination',
  59. scrollDelta: 1500
  60. }
  61. },
  62. iao_su_postslist: {
  63. SiteTypeID: 3,
  64. pager: {
  65. type: 1,
  66. nextLink: '//li[@class="btn btn-primary next"]//a[@href]',
  67. pageElement: 'css;#index > article, #archive > article',
  68. HT_insert: ['css;ol.page-navigator', 1],
  69. replaceE: 'css;ol.page-navigator',
  70. scrollDelta: 800,
  71. beforeFunction: iao_su_postslist_beforeFunction
  72. }
  73. },
  74. appinn_postslist: {
  75. SiteTypeID: 4,
  76. pager: {
  77. type: 1,
  78. nextLink: '//a[@class="next page-numbers"][@href]',
  79. pageElement: 'css;section#latest-posts > article',
  80. HT_insert: ['css;nav.navigation.pagination', 1],
  81. replaceE: 'css;div.nav-links',
  82. scrollDelta: 1500
  83. }
  84. },
  85. iplaysoft_postslist: {
  86. SiteTypeID: 5,
  87. pager: {
  88. type: 1,
  89. nextLink: '//div[@class="pagenavi"]//a[@title="下一页"][@href]',
  90. pageElement: 'css;#postlist > div.entry',
  91. HT_insert: ['css;#postlist > .pagenavi-button', 1],
  92. replaceE: 'css;.pagenavi-button, .pagenavi',
  93. scrollDelta: 1200,
  94. beforeFunction: iplaysoft_postslist_beforeFunction
  95. }
  96. },
  97. iplaysoft_postcomments: {
  98. SiteTypeID: 6,
  99. pager: {
  100. type: 2,
  101. nextLink: '#loadHistoryComments',
  102. nextText: '展开后面',
  103. scrollDelta: 1200
  104. }
  105. },
  106. sanguosha_forum: {
  107. SiteTypeID: 7,
  108. pager: {
  109. type: 2,
  110. nextLink: '#autopbn',
  111. nextText: '下一页 »',
  112. scrollDelta: 800
  113. }
  114. },
  115. sanguosha_thread: {
  116. SiteTypeID: 8,
  117. pager: {
  118. type: 1,
  119. nextLink: '//a[@class="nxt"][@href]',
  120. pageElement: 'css;div#postlist > div[id^="post_"]',
  121. HT_insert: ['css;div#postlist', 3],
  122. replaceE: 'css;div.pg',
  123. scrollDelta: 800
  124. }
  125. },
  126. sanguosha_search: {
  127. SiteTypeID: 9,
  128. pager: {
  129. type: 1,
  130. nextLink: '//a[@class="nxt"][@href]',
  131. pageElement: 'css;div#threadlist > ul',
  132. HT_insert: ['css;div#threadlist', 3],
  133. replaceE: 'css;div.pg',
  134. scrollDelta: 800
  135. }
  136. },
  137. pubmed_postslist: {
  138. SiteTypeID: 10,
  139. pager: {
  140. type: 2,
  141. nextLink: 'button.load-button.next-page',
  142. nextText: 'Show more',
  143. scrollDelta: 1500
  144. }
  145. },
  146. wall_alphacoders: {
  147. SiteTypeID: 11,
  148. pager: {
  149. type: 1,
  150. nextLink: '//a[@id="next_page"][@href]',
  151. pageElement: 'css;.thumb-container-big, .avatar-thumb, .thumb-element',
  152. HT_insert: ['css;.thumb-container-big:nth-last-child(1), .avatar-thumb:nth-last-child(1), .thumb-element:nth-last-child(1)', 4],
  153. replaceE: '//div[@class="hidden-xs hidden-sm"]/..',
  154. scrollDelta: 1000
  155. }
  156. }
  157. };
  158.  
  159.  
  160. switch (location.host) {
  161. case "www.423down.com":
  162. curSite = DBSite._423down_postslist;
  163. break;
  164. case "apphot.cc":
  165. curSite = DBSite.apphot_postslist;
  166. break;
  167. case "iao.su":
  168. curSite = DBSite.iao_su_postslist;
  169. break;
  170. case "www.appinn.com":
  171. curSite = DBSite.appinn_postslist;
  172. break;
  173. case "www.iplaysoft.com":
  174. if(location.pathname.indexOf(".html") > -1 || location.pathname.indexOf("/p/") > -1){ // 文章内
  175. curSite = DBSite.iplaysoft_postcomments;
  176. }else{ // 其他页面
  177. curSite = DBSite.iplaysoft_postslist;
  178. }
  179. break;
  180. case "wall.alphacoders.com":
  181. case "avatars.alphacoders.com":
  182. case "mobile.alphacoders.com":
  183. curSite = DBSite.wall_alphacoders;
  184. break;
  185. case "club.sanguosha.com":
  186. if(location.pathname.indexOf("forum") > -1){ // 各版块帖子列表
  187. curSite = DBSite.sanguosha_forum;
  188. }else if(location.pathname.indexOf("thread") > -1){ // 帖子内
  189. curSite = DBSite.sanguosha_thread;
  190. hidePgbtn(); // 隐藏帖子内的 [下一页] 按钮
  191. }else if(location.pathname.indexOf("search") > -1){ // 搜索结果
  192. curSite = DBSite.sanguosha_search;
  193. }
  194. break;
  195. case "pubmed.ncbi.nlm.nih.gov":
  196. curSite = DBSite.pubmed_postslist;
  197. break;
  198. }
  199. curSite.pageUrl = ""; // 下一页URL
  200. pageLoading(); // 自动无缝翻页
  201.  
  202.  
  203. // 自动无缝翻页
  204. function pageLoading() {
  205. if (curSite.SiteTypeID > 0){
  206. windowScroll(function (direction, e) {
  207. if (direction === "down") { // 下滑才准备翻页
  208. let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
  209. let scrollDelta = curSite.pager.scrollDelta;
  210. if (document.documentElement.scrollHeight <= document.documentElement.clientHeight + scrollTop + scrollDelta) {
  211. if (curSite.pager.type === 1) {
  212. ShowPager.loadMorePage();
  213. }else{
  214. let autopbn = document.querySelector(curSite.pager.nextLink);
  215. if (autopbn){ // 如果正在加载,就不再点击
  216. if (!curSite.pager.nextText){ // 如果没有指定 nextText 就直接点击
  217. autopbn.click();
  218. }else if (autopbn.innerText.indexOf(curSite.pager.nextText) > -1){ // 如果指定了 nextText 就需要判断后再点击(避免已经在加载了,还重复点击)
  219. autopbn.click();
  220. }
  221. }
  222. }
  223. }
  224. }
  225. });
  226. }
  227. }
  228.  
  229.  
  230. // 隐藏帖子内的 [下一页] 按钮
  231. function hidePgbtn(){
  232. let style_hidePgbtn = document.createElement('style');
  233. style_hidePgbtn.innerHTML = `.pgbtn {display: none;}`;
  234. document.head.appendChild(style_hidePgbtn);
  235. }
  236.  
  237.  
  238. // iplaysoft 的插入前函数
  239. function iplaysoft_postslist_beforeFunction(pageElems) {
  240. pageElems.forEach(function (one) {
  241. let now = one.querySelector("img.lazyload")
  242. if (now && !now.getAttribute('src')) {
  243. now.setAttribute("src",now.getAttribute('data-src'))
  244. now.setAttribute("srcset",now.getAttribute('data-src'))
  245. now.setAttribute("class","lazyloaded")
  246. }
  247. });
  248. return pageElems
  249. }
  250.  
  251.  
  252. // iao.su 的插入前函数
  253. function iao_su_postslist_beforeFunction(pageElems) {
  254. pageElems.forEach(function (one) {
  255. let now = one.getElementsByClassName("post-card")[0]
  256. if (now) {
  257. now.getElementsByClassName("blog-background")[0].style.backgroundImage = 'url("' + RegExp("(?<=loadBannerDirect\\(').*(?=', '',)").exec(now.getElementsByTagName("script")[0].innerText)[0]; + '")';
  258. }
  259. });
  260. return pageElems
  261. }
  262.  
  263.  
  264. // 滚动条事件
  265. function windowScroll(fn1) {
  266. var beforeScrollTop = document.documentElement.scrollTop,
  267. fn = fn1 || function () {};
  268. setTimeout(function () { // 延时执行,避免刚载入到页面就触发翻页事件
  269. window.addEventListener("scroll", function (e) {
  270. var afterScrollTop = document.documentElement.scrollTop,
  271. delta = afterScrollTop - beforeScrollTop;
  272. if (delta == 0) return false;
  273. fn(delta > 0 ? "down" : "up", e);
  274. beforeScrollTop = afterScrollTop;
  275. }, false);
  276. }, 1000)
  277. }
  278.  
  279.  
  280. var ShowPager = { // 修改自 https://gf.qytechs.cn/scripts/14178
  281. getFullHref: function (e) {
  282. if(e == null) return '';
  283. "string" != typeof e && (e = e.getAttribute("href"));
  284. var t = this.getFullHref.a;
  285. return t || (this.getFullHref.a = t = document.createElement("a")), t.href = e, t.href;
  286. },
  287. createDocumentByString: function (e) {
  288. if (e) {
  289. if ("HTML" !== document.documentElement.nodeName) return (new DOMParser).parseFromString(e, "application/xhtml+xml");
  290. var t;
  291. try {
  292. t = (new DOMParser).parseFromString(e, "text/html");
  293. } catch (e) {
  294. }
  295. if (t) return t;
  296. if (document.implementation.createHTMLDocument) t = document.implementation.createHTMLDocument("ADocument"); else try {
  297. (t = document.cloneNode(!1)).appendChild(t.importNode(document.documentElement, !1)),
  298. t.documentElement.appendChild(t.createElement("head")), t.documentElement.appendChild(t.createElement("body"));
  299. } catch (e) {
  300. }
  301. if (t) {
  302. var r = document.createRange();
  303. r.selectNodeContents(document.body);
  304. var n = r.createContextualFragment(e);
  305. t.body.appendChild(n);
  306. for (var a, o = {
  307. TITLE: !0,
  308. META: !0,
  309. LINK: !0,
  310. STYLE: !0,
  311. BASE: !0
  312. }, i = t.body, s = i.childNodes, c = s.length - 1; c >= 0; c--) o[(a = s[c]).nodeName] && i.removeChild(a);
  313. return t;
  314. }
  315. } else console.error("没有找到要转成DOM的字符串");
  316. },
  317. loadMorePage: function () {
  318. if (curSite.pager) {
  319. let curPageEle = getElementByXpath(curSite.pager.nextLink);
  320. var url = this.getFullHref(curPageEle);
  321. console.log(`${url} ${curPageEle} ${curSite.pageUrl}`);
  322. if(url === '') return;
  323. if(curSite.pageUrl === url) return;// 避免重复加载相同的页面
  324. curSite.pageUrl = url;
  325. // 读取下一页的数据
  326. curSite.pager.startFilter && curSite.pager.startFilter();
  327. GM_xmlhttpRequest({
  328. url: url,
  329. method: "GET",
  330. timeout: 5000,
  331. onload: function (response) {
  332. try {
  333. //console.log(`${response.responseText}`)
  334. var newBody = ShowPager.createDocumentByString(response.responseText);
  335. let pageElems = getAllElements(curSite.pager.pageElement, newBody, newBody);
  336. let toElement = getAllElements(curSite.pager.HT_insert[0])[0];
  337. if (pageElems.length >= 0) {
  338. // 如果有插入前函数就执行函数
  339. if (curSite.pager.beforeFunction)pageElems = curSite.pager.beforeFunction(pageElems);
  340. // 插入位置
  341. let addTo;
  342. switch (curSite.pager.HT_insert[1]) {
  343. case 1:
  344. addTo = "beforebegin"
  345. break;
  346. case 2:
  347. addTo = "afterbegin"
  348. break;
  349. case 3:
  350. addTo = "beforeend"
  351. break;
  352. case 4:
  353. addTo = "afterend"
  354. break;
  355. }
  356. // 插入新页面元素
  357. pageElems.forEach(function (one) {
  358. toElement.insertAdjacentElement(addTo, one);
  359. });
  360. // 替换待替换元素
  361. try {
  362. let oriE = getAllElements(curSite.pager.replaceE);
  363. let repE = getAllElements(curSite.pager.replaceE, newBody, newBody);
  364. if (oriE.length === repE.length) {
  365. for (var i = 0; i < oriE.length; i++) {
  366. oriE[i].outerHTML = repE[i].outerHTML;
  367. }
  368. }
  369. } catch (e) {
  370. console.log(e);
  371. }
  372. // 如果有插入后函数就执行函数
  373. if (curSite.pager.afterFunction)curSite.pager.afterFunction();
  374. }
  375. } catch (e) {
  376. console.log(e);
  377. }
  378. }
  379. });
  380. }
  381. },
  382. };
  383.  
  384.  
  385. function getElementByXpath(e, t, r) {
  386. r = r || document, t = t || r;
  387. try {
  388. return r.evaluate(e, t, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  389. } catch (t) {
  390. return void console.error("无效的xpath");
  391. }
  392. }
  393.  
  394.  
  395. function getAllElements(e, t, r, n, o) {
  396. let getAllElementsByXpath = function(e, t, r) {
  397. return r = r || document, t = t || r, r.evaluate(e, t, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  398. }
  399.  
  400. var i, s = [];
  401. if (!e) return s;
  402. if (r = r || document, n = n || window, o = o || void 0, t = t || r, "string" == typeof e) i = 0 === e.search(/^css;/i) ? function getAllElementsByCSS(e, t) {
  403. return (t || document).querySelectorAll(e);
  404. }(e.slice(4), t) : getAllElementsByXpath(e, t, r); else {
  405. if (!(i = e(r, n, o))) return s;
  406. if (i.nodeType) return s[0] = i, s;
  407. }
  408. return function makeArray(e) {
  409. var t, r, n, o = [];
  410. if (e.pop) {
  411. for (t = 0, r = e.length; t < r; t++) (n = e[t]) && (n.nodeType ? o.push(n) : o = o.concat(makeArray(n)));
  412. return a()(o);
  413. }
  414. if (e.item) {
  415. for (t = e.length; t;) o[--t] = e[t];
  416. return o;
  417. }
  418. if (e.iterateNext) {
  419. for (t = e.snapshotLength; t;) o[--t] = e.snapshotItem(t);
  420. return o;
  421. }
  422. }(i);
  423. }
  424. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址