自动无缝翻页

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

当前为 2021-04-09 提交的版本,查看 最新版本

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

QingJ © 2025

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