[{"bookSourceName":"搬山人","bookSourceUrl":"https:\/\/www.banshanren.com","bookSourceGroup":"小说","bookSourceType":0,"bookUrlPattern":"https?:\/\/www\\.banshanren\\.com\/novel\/[^\/?#]+\/?$","enabled":true,"enabledExplore":true,"enabledCookieJar":true,"concurrentRate":"1\/5000","lastUpdateTime":"1791318668140","bookSourceComment":"2026-10-07 五段预览检查版。提取前检查整张网页的data-code、验证码按钮和正文段数。发现访问限制或恰好5段时打开本章原网页，需手动完成网站验证后点右上角完成；直接使用浏览器返回的页面，不额外重请求。若仍受限或仍为5段则报错，不保存残缺章节（确实只有5段的真实短章也会触发此检查）。删除未经证实的下一章续页规则。请求UA与内置浏览器一致。导入覆盖后必须清除原书章节缓存再刷新。搜索、目录、分类沿用。封面未解密。已用Rhino\/Jsoup验证提取及拦截逻辑；手机验证码流程需实测。","header":"@js:JSON.stringify({\"User-Agent\":java.getWebViewUA(),\"Referer\":\"https:\/\/www.banshanren.com\/\"})","searchUrl":"\/api\/search?keyword={{java.encodeURI(key)}}&page={{page}}","ruleSearch":{"bookList":"$.model.data[*]","name":"$.title","author":"$.authors","bookUrl":"\/novel\/{{$.slug}}","intro":"$.brief","kind":"$.tagNames[*]","wordCount":"$.wordCount","lastChapter":"$.latestUpdate"},"exploreUrl":"全部小说::\/all\/0-0-0-0-0-0-1-{{page}}\/\n最近更新::\/all\/0-0-0-0-0-0-2-{{page}}\/\n热门小说::\/all\/0-0-0-0-0-0-3-{{page}}\/\n奇幻玄幻::\/all\/0-4-0-0-0-0-1-{{page}}\/\n现代都市::\/all\/0-3-0-0-0-0-1-{{page}}\/\n穿越重生::\/all\/0-7-0-0-0-0-1-{{page}}\/\n武侠仙侠::\/all\/0-8-0-0-0-0-1-{{page}}\/\nBG言情::\/all\/0-5-0-0-0-0-1-{{page}}\/\nBL耽美::\/all\/0-1-0-0-0-0-1-{{page}}\/\nGL百合::\/all\/0-2-0-0-0-0-1-{{page}}\/","ruleExplore":{"bookList":"@css:.main_box > .novel_list > li.novel_li","name":"@css:a.title@text","bookUrl":"@css:a.title@href","author":"@css:.title_box > .info_box:last-of-type@text##\\s*·[\\s\\S]*$##","wordCount":"@css:.title_box > .info_box:last-of-type@text##^[\\s\\S]*·\\s*##","kind":"@css:.category_list a@text","intro":"@css:.novel_intro_box@text"},"ruleBookInfo":{"name":"@css:.novel_title_box h1@text","author":"@css:.novel_title_box [title=作者]@text","intro":"@css:meta[property=\"og:description\"]@content","kind":"@css:.novel_title_box > .category_list a@text","wordCount":"@css:.novel_summary_box.pc > div:last-child b@text","tocUrl":"@js:baseUrl","lastChapter":"@css:.catalog_top_box .hl@text"},"ruleToc":{"chapterList":"@css:.chapter_list li.volume_chapter","chapterName":"@css:a@text","chapterUrl":"@css:a@href"},"ruleContent":{"title":"@css:.chapter_content_box > h2@text","content":"@js:var pageUrl = String(baseUrl);\nfunction inspectPage(markup) {\n    java.setContent(String(markup), pageUrl);\n    var documents = java.getElements('@css:html');\n    if (documents.size() === 0) throw new Error('没有取得网页，请刷新本章');\n    var doc = documents.get(0);\n    var chapterBox = doc.select('.chapter_box').first();\n    var contentBox = doc.select('.chapter_content_box').first();\n    var paragraphs = doc.select('.chapter_content_box > p');\n    var code = chapterBox === null ? '' : String(chapterBox.attr('data-code'));\n    var notice = String(contentBox === null ? doc.text() : contentBox.text()).replace(\/\\s+\/g, '');\n    var captcha = \/系统检测到.{0,15}访问异常|输入验证码后可继续访问\/.test(notice)\n        || doc.select('#captcha_btn,[onclick*=toggleCode]').size() > 0;\n    var restricted = code !== '' && code !== '0';\n    return {doc: doc, paragraphs: paragraphs, count: paragraphs.size(), code: code, captcha: captcha, restricted: restricted};\n}\nvar state = inspectPage(result);\njava.log('搬山人正文检查：段落=' + state.count + '，状态=' + state.code + '，验证提示=' + state.captcha);\nif (state.captcha || state.restricted || state.count === 5) {\n    if (typeof java.startBrowserAwait !== 'function') {\n        throw new Error('本章疑似受限预览（' + state.count + '段）。请在阅读内置浏览器打开本章原网页完成验证；当前版本不支持自动验证窗口。');\n    }\n    var verified = java.startBrowserAwait(pageUrl, '请验证并确认本章正文已完整显示，再点右上角完成', false);\n    if (verified === null) throw new Error('没有取得验证后的网页，请重新打开本章原网页');\n    state = inspectPage(String(verified.body()));\n    java.log('搬山人验证后检查：段落=' + state.count + '，状态=' + state.code + '，验证提示=' + state.captcha);\n    if (state.captcha || state.restricted) {\n        throw new Error('原网页仍限制本章访问（状态=' + state.code + '，' + state.count + '段）。请完成验证码或网站要求的登录后再试。');\n    }\n    if (state.count === 5) {\n        throw new Error('验证后的网页仍只有5段，已停止保存，避免再次缓存截断内容。请检查原网页是否完整；恰好5段的真实短章也会触发此检查。');\n    }\n}\nif (state.count === 0) throw new Error('网页未提供正文段落，请在原网页检查访问状态');\nvar clean = state.paragraphs.clone();\nclean.select('span[onclick^=togglePostComment],span[class*=count_]').remove();\nString(clean.outerHtml());\n"},"loginUrl":"https:\/\/www.banshanren.com\/"}]