🐾顶点小说xsbook
http://www.xsbook.org
laizhiyu (6509)11/01 02:53
🐾顶点小说xsbook 修复版 v2.0 (2026-10-31)
【核心修复】
1. 站点反爬=403双击验证:新会话首击403+Set-Cookie,带Cookie二击200。旧版 enabledCookieJar=false 且搜索规则先 removeCookie 再裸请求→永远403。
修复:enabledCookieJar=true + 全站请求URL选项 retry:2(403→存Cookie→自动重发→200)。
2. 搜索action路径轮换(search7b.html→search3d.html...),searchUrl用@js动态从首页form提取当前action(旧版设计本意如此,但旧版因removeCookie+无retry而失效)。
3. 简介三级兜底:og:description→id.intro→meta[name=description]。
4. 目录:最新段9条(新→旧)+完整段(旧→新)→JS按href保后去重得完整正序1299章。
5. 发现页补全 ruleExplore(旧版为空),全站列表页统一 class.item。
6. 封面懒加载,真图在 data-original(旧版img@src全是占位图)。
7. 全本分页 /quanben/xclass/{page}.html(旧版无页码)。
【风控】①搜索限频是"会话级":同会话搜索间隔30秒(触发返回200+59字节alert"搜索间隔: 30 秒"空页),会话被刷爆后持续被限(等再久也没用)。解法=searchUrl每次搜索前 cookie.removeCookie 换新会话(旧版设计本意),配合 enabledCookieJar+retry:2 完成 403双击拿新Cookie。②全站对快速连发敏感(触发IP级风控升级后连Cookie都不下发),已设 concurrentRate 1/8000(实测甜点值:8秒间隔站点直接放行;间隔更短(1秒)会被站点挂起到30秒才响应,更长则拖慢校验/下载;搜索30秒会话限频靠每次换新会话规避,不受此影响)。
【登录】站点无需登录。登录面板=发布页线路管理:发布页输入框/一键获取线路/测延时/点选切换。
【v2.5】站点会话在请求间隔后可能对任意页面重新触发403二次验证,详情页/章节页/下一页URL统一追加 {"retry":2} 由Legado自动双击过验证。 {
"bookSourceComment": "🐾顶点小说xsbook 修复版 v2.0 (2026-10-31)\n\n【核心修复】\n1. 站点反爬=403双击验证:新会话首击403+Set-Cookie,带Cookie二击200。旧版 enabledCookieJar=false 且搜索规则先 removeCookie 再裸请求→永远403。\n 修复:enabledCookieJar=true + 全站请求URL选项 retry:2(403→存Cookie→自动重发→200)。\n2. 搜索action路径轮换(search7b.html→search3d.html...),searchUrl用@js动态从首页form提取当前action(旧版设计本意如此,但旧版因removeCookie+无retry而失效)。\n3. 简介三级兜底:og:description→id.intro→meta[name=description]。\n4. 目录:最新段9条(新→旧)+完整段(旧→新)→JS按href保后去重得完整正序1299章。\n5. 发现页补全 ruleExplore(旧版为空),全站列表页统一 class.item。\n6. 封面懒加载,真图在 data-original(旧版img@src全是占位图)。\n7. 全本分页 \/quanben\/xclass\/{page}.html(旧版无页码)。\n\n【风控】①搜索限频是\"会话级\":同会话搜索间隔30秒(触发返回200+59字节alert\"搜索间隔: 30 秒\"空页),会话被刷爆后持续被限(等再久也没用)。解法=searchUrl每次搜索前 cookie.removeCookie 换新会话(旧版设计本意),配合 enabledCookieJar+retry:2 完成 403双击拿新Cookie。②全站对快速连发敏感(触发IP级风控升级后连Cookie都不下发),已设 concurrentRate 1\/8000(实测甜点值:8秒间隔站点直接放行;间隔更短(1秒)会被站点挂起到30秒才响应,更长则拖慢校验\/下载;搜索30秒会话限频靠每次换新会话规避,不受此影响)。\n\n【登录】站点无需登录。登录面板=发布页线路管理:发布页输入框\/一键获取线路\/测延时\/点选切换。\n\n【v2.5】站点会话在请求间隔后可能对任意页面重新触发403二次验证,详情页\/章节页\/下一页URL统一追加 {\"retry\":2} 由Legado自动双击过验证。",
"bookSourceGroup": "顶点小说",
"bookSourceName": "🐾顶点小说xsbook",
"bookSourceType": 0,
"bookSourceUrl": "http:\/\/www.xsbook.org",
"concurrentRate": "1\/8000",
"customButton": false,
"customOrder": 0,
"enabled": true,
"enabledCookieJar": true,
"enabledExplore": true,
"eventListener": false,
"exploreUrl": "[{\"title\":\"♨️分类·排行♨️\",\"url\":\"\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":1.0}},{\"title\":\"玄幻\",\"url\":\"\/xclass\/1\/{{page}}.html,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"武侠\",\"url\":\"\/xclass\/2\/{{page}}.html,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"女频\",\"url\":\"\/xclass\/3\/{{page}}.html,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"现代\",\"url\":\"\/xclass\/4\/{{page}}.html,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"历史\",\"url\":\"\/xclass\/5\/{{page}}.html,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"游戏\",\"url\":\"\/xclass\/6\/{{page}}.html,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"科幻\",\"url\":\"\/xclass\/7\/{{page}}.html,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"美文\",\"url\":\"\/xclass\/8\/{{page}}.html,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"其他\",\"url\":\"\/xclass\/9\/{{page}}.html,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"全本\",\"url\":\"\/quanben\/xclass\/{{page}}.html,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"总排行榜\",\"url\":\"\/rank\/allvisit\/,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"月排行榜\",\"url\":\"\/rank\/monthvisit\/,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"周排行榜\",\"url\":\"\/rank\/weekvisit\/,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}},{\"title\":\"收藏榜\",\"url\":\"\/rank\/goodnum\/,{\\\"retry\\\":2}\",\"style\":{\"layout_flexGrow\":1,\"layout_flexBasisPercent\":0.25}}]",
"header": "{\"User-Agent\": \"Mozilla\/5.0 (Linux; Android 14; Pixel 8) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/124.0.6367.82 Mobile Safari\/537.36\"}",
"lastUpdateTime": "1793472828629",
"loginUi": "[{\"name\": \"ℹ️ 本站无需登录|面板=发布页线路管理\", \"type\": \"text\", \"action\": \"XSB_noop(java)\"}, {\"name\": \"📡 当前线路\", \"type\": \"text\", \"action\": \"XSB_showLine(java)\", \"viewName\": \"'📡 当前线路: '+(source.get('xsb_line')?String(source.get('xsb_line')).replace(\/^https?:\\\\\/\\\\\/\/,''):'主站 www.xsbook.org')\"}, {\"name\": \"🔗 发布页地址\", \"type\": \"text\", \"action\": \"XSB_setPub(java)\", \"default\": \"https:\/\/www.xsbook.org\"}, {\"name\": \"①从发布页获取线路\", \"type\": \"button\", \"action\": \"XSB_fetchLines(java)\"}, {\"name\": \"②测延时(全部线路)\", \"type\": \"button\", \"action\": \"XSB_speedTest(java)\"}, {\"name\": \"🌐 线路1\", \"type\": \"button\", \"action\": \"XSB_useLine(java,1)\", \"viewName\": \"var a=String(source.get('xsb_line1')||'');a?a.replace(\/^https?:\\\\\/\\\\\/\/,'').substring(0,26)+' '+(source.get('xsb_sp1')||''):'(空位1)'\"}, {\"name\": \"🌐 线路2\", \"type\": \"button\", \"action\": \"XSB_useLine(java,2)\", \"viewName\": \"var a=String(source.get('xsb_line2')||'');a?a.replace(\/^https?:\\\\\/\\\\\/\/,'').substring(0,26)+' '+(source.get('xsb_sp2')||''):'(空位2)'\"}, {\"name\": \"🌐 线路3\", \"type\": \"button\", \"action\": \"XSB_useLine(java,3)\", \"viewName\": \"var a=String(source.get('xsb_line3')||'');a?a.replace(\/^https?:\\\\\/\\\\\/\/,'').substring(0,26)+' '+(source.get('xsb_sp3')||''):'(空位3)'\"}, {\"name\": \"🌐 线路4\", \"type\": \"button\", \"action\": \"XSB_useLine(java,4)\", \"viewName\": \"var a=String(source.get('xsb_line4')||'');a?a.replace(\/^https?:\\\\\/\\\\\/\/,'').substring(0,26)+' '+(source.get('xsb_sp4')||''):'(空位4)'\"}, {\"name\": \"🌐 线路5\", \"type\": \"button\", \"action\": \"XSB_useLine(java,5)\", \"viewName\": \"var a=String(source.get('xsb_line5')||'');a?a.replace(\/^https?:\\\\\/\\\\\/\/,'').substring(0,26)+' '+(source.get('xsb_sp5')||''):'(空位5)'\"}, {\"name\": \"🌐 线路6\", \"type\": \"button\", \"action\": \"XSB_useLine(java,6)\", \"viewName\": \"var a=String(source.get('xsb_line6')||'');a?a.replace(\/^https?:\\\\\/\\\\\/\/,'').substring(0,26)+' '+(source.get('xsb_sp6')||''):'(空位6)'\"}, {\"name\": \"💡 获取线路→测延时→点线路按钮切换\", \"type\": \"text\", \"action\": \"XSB_noop(java)\"}]",
"loginUrl": "<js>\n\/\/ ===== xsbook 发布页线路管理函数库 v2.0 =====\n\/\/ action 统一签名 XSB_xxx(java),调用侧传 java(SourceLoginJsExtensions)\n\/\/ 变量键: xsb_pub=发布页 xsb_line=当前线路 xsb_lineN\/xsb_spN=线路N与延时\nfunction XSB_gv(jv, k, d) {\n var v = '';\n try { v = String(jv.get(k) || ''); } catch (e) {}\n if (!v || v == 'null' || v == 'undefined') v = d || '';\n return v;\n}\nfunction XSB_T(jv, msg) {\n var ok = false;\n try { jv.longToast(msg); ok = true; } catch (e) {}\n if (!ok) { try { jv.toast(msg); ok = true; } catch (e2) {} }\n if (!ok) { try { jv.copyText(msg); } catch (e3) {} }\n}\nfunction XSB_noop(jv) {\n XSB_T(jv, 'ℹ️ 本站无需登录。面板用法: 发布页输入框可改发布页→点①获取线路→②测延时→点线路按钮切换');\n}\nfunction XSB_showLine(jv) {\n var cur = XSB_gv(jv, 'xsb_line', '');\n if (cur) {\n XSB_T(jv, '📡 当前线路: ' + cur);\n } else {\n XSB_T(jv, '📡 当前线路: 主站 http:\/\/www.xsbook.org');\n }\n try { jv.reLoginView(); } catch (e) { try { jv.reUiView(); } catch (e2) {} }\n}\nfunction XSB_setPub(jv) {\n var p = '';\n try {\n var m = source.getLoginInfoMap();\n if (m && m.get) { p = String(m.get('🔗 发布页地址') || ''); }\n } catch (e) {}\n if (!p) { p = XSB_gv(jv, 'xsb_pub', ''); }\n p = p.trim();\n if (!p) {\n XSB_T(jv, '⚠️ 输入框为空,未修改。当前发布页: ' + (XSB_gv(jv, 'xsb_pub', '默认 https:\/\/www.xsbook.org')));\n return;\n }\n if (p.indexOf('http') !== 0) { p = 'http:\/\/' + p; }\n source.put('xsb_pub', p);\n XSB_T(jv, '✅ 发布页已保存: ' + p + ' | 下一步点①获取线路');\n}\nfunction XSB_fetchLines(jv) {\n XSB_T(jv, '⏳ 正在从发布页获取线路...');\n var pub = XSB_gv(jv, 'xsb_pub', 'https:\/\/www.xsbook.org');\n var html = '';\n try { html = String(jv.ajax(pub)); } catch (e) { html = ''; }\n var lines = [];\n if (html.length >= 100) {\n var ms = html.match(\/href=\"(https?:\\\/\\\/[^\"]*xsbook[^\"]*)\"\/g) || [];\n for (var i = 0; i < ms.length; i++) {\n var u = ms[i].replace(\/href=\"(https?:\\\/\\\/[^\"]*)\"\/, '$1');\n if (u.indexOf('xsbooktxt') > -1) { continue; }\n if (lines.indexOf(u) < 0) { lines.push(u); }\n }\n }\n if (lines.length === 0) {\n lines.push('http:\/\/www.xsbook.org');\n XSB_T(jv, '⚠️ 发布页未解析到线路(可能被墙),已填主站兜底');\n }\n source.put('xsb_lines', JSON.stringify(lines));\n for (var i = 1; i <= 6; i++) {\n if (i <= lines.length) { source.put('xsb_line' + i, lines[i - 1]); }\n else { source.put('xsb_line' + i, ''); }\n source.put('xsb_sp' + i, '');\n }\n XSB_T(jv, '✅ 获取到 ' + lines.length + ' 条线路:\\n' + lines.join('\\n'));\n try { jv.reLoginView(); } catch (e) { XSB_T(jv, '提示: 重新打开面板可见线路按钮'); }\n}\nfunction XSB_speedTest(jv) {\n XSB_T(jv, '⏳ 正在测延时(每线路8秒超时)...');\n var lines = [];\n for (var i = 1; i <= 6; i++) {\n var a = XSB_gv(jv, 'xsb_line' + i, '');\n if (a) { lines.push(a); }\n }\n if (lines.length === 0) { XSB_T(jv, '⚠️ 请先点①获取线路'); return; }\n var best = '';\n var bm = 99999999;\n var msg = '';\n for (var i = 0; i < lines.length; i++) {\n var t0 = Date.now();\n var st = '超时';\n var ok = false;\n var u = lines[i] + ',{\"timeout\":8000,\"retry\":0}';\n try {\n var b = String(jv.ajax(u));\n if (b.length > 5000) { ok = true; st = (Date.now() - t0) + 'ms'; }\n } catch (e) { st = '失败'; }\n source.put('xsb_sp' + (i + 1), st);\n msg += '\\n' + lines[i].replace(\/^https?:\\\/\\\/\/, '') + ' ' + st;\n if (ok && (Date.now() - t0) < bm) { bm = Date.now() - t0; best = lines[i]; }\n }\n if (best) {\n var bi = lines.indexOf(best);\n source.put('xsb_sp' + (bi + 1), '⚡' + XSB_gv(jv, 'xsb_sp' + (bi + 1), st));\n }\n XSB_T(jv, '✅ 测延时完成(⚡最快):\\n' + msg);\n try { jv.reLoginView(); } catch (e) {}\n}\nfunction XSB_useLine(jv, n) {\n var a = XSB_gv(jv, 'xsb_line' + n, '');\n if (!a) { XSB_T(jv, '⚠️ 线路' + n + ' 为空,请先点①获取线路'); return; }\n source.put('xsb_line', a);\n XSB_T(jv, '✅ 已记录线路: ' + a + '\\n⚠️ 本源请求固定走 bookSourceUrl 主站,切换仅作记录;域名变动请编辑书源改 bookSourceUrl');\n try { jv.reLoginView(); } catch (e) {}\n}\n<\/js>",
"respondTime": 180000,
"ruleBookInfo": {
"author": "[property=\"og:novel:author\"]@content",
"coverUrl": "[property=\"og:image\"]@content",
"intro": "[property=\"og:description\"]@content||id.intro@text||[name=\"description\"]@content",
"kind": "[property=\"og:novel:category\"]@content&&[property=\"og:novel:status\"]@content",
"lastChapter": "[property=\"og:novel:lastest_chapter_name\"]@content",
"name": "[property=\"og:novel:book_name\"]@content"
},
"ruleContent": {
"content": "id.booktxt@html",
"nextContentUrl": "id.next_url.0@href\n@js:var u=result;try{if(u.size){u=u.get(0)}}catch(e){}String(u)+',{\"retry\":2}'",
"replaceRegex": "##(本站所有小说均由根据搜索引擎转码而来[\\s\\S]*|请记住本书首发域名[\\s\\S]*|顶点小说.*?www\\.xsbook\\.org|www\\.xsbook\\.org)##g"
},
"ruleExplore": {
"author": "class.btm@a@text",
"bookList": "class.item",
"bookUrl": "a.0@href\n@js:String(result) + ',{\"retry\":2}'",
"coverUrl": "img@data-original",
"intro": "dl@dd@text",
"kind": "em.0:1@text",
"name": "dl@dt@a@text"
},
"ruleSearch": {
"author": "class.btm@a@text",
"bookList": "class.item",
"bookUrl": "a.0@href\n@js:String(result) + ',{\"retry\":2}'",
"coverUrl": "img@data-original",
"intro": "dl@dd@text",
"kind": "em.0:1@text",
"name": "dl@dt@a@text"
},
"ruleToc": {
"chapterList": "id.list@dl>a\n@js:var seen={};var out=[];for(var i=result.length-1;i>=0;i--){var u=String(result[i].attr(\"href\")||\"\");if(u&&!seen[u]){seen[u]=1;out.unshift(result[i])}}out;",
"chapterName": "text",
"chapterUrl": "href\n@js:String(result) + ',{\"retry\":2}'"
},
"searchUrl": "@js:var base = \"http:\/\/www.xsbook.org\";try { cookie.removeCookie(base); } catch (e) {}var h = String(java.ajax(base + \"\/,{\\\"retry\\\":2}\"));var m = h.match(\/<form[^>]*action=\"([^\"]*)\"\/);var act = m ? m[1] : \"\/search7b.html\";base + act + \"?searchkey={{key}},{\\\"retry\\\":2}\";",
"weight": 0
}