[{"bookSourceComment":"85小說網；2026-05-23 修复搜索：旧 search.php?k 接口已不适配，改用新版 GET \/search?k={{key}}&page={{page}}；搜索列表采用 Tailwind 卡片 div.flex.flex-col.gap-2；目录不是静态完整 HTML，需从详情页 x-data token + POST action=chapters 分段补全。","bookSourceGroup":"GPT制作书源","bookSourceName":"85小說網","bookSourceType":0,"bookSourceUrl":"https:\/\/www.85novel.com","customOrder":4,"enabled":true,"enabledCookieJar":true,"enabledExplore":true,"exploreUrl":"[{\"title\": \"最新更新\", \"url\": \"\/list\/index\", \"style\": {\"layout_flexGrow\": 1}}, {\"title\": \"玄幻奇幻\", \"url\": \"\/list\/667\/{{page==1?'':'page'+page+'\/'}}\", \"style\": {\"layout_flexGrow\": 1}}, {\"title\": \"仙俠武俠\", \"url\": \"\/list\/668\/{{page==1?'':'page'+page+'\/'}}\", \"style\": {\"layout_flexGrow\": 1}}, {\"title\": \"都市生活\", \"url\": \"\/list\/669\/{{page==1?'':'page'+page+'\/'}}\", \"style\": {\"layout_flexGrow\": 1}}, {\"title\": \"歷史軍事\", \"url\": \"\/list\/670\/{{page==1?'':'page'+page+'\/'}}\", \"style\": {\"layout_flexGrow\": 1}}, {\"title\": \"遊戲競技\", \"url\": \"\/list\/671\/{{page==1?'':'page'+page+'\/'}}\", \"style\": {\"layout_flexGrow\": 1}}, {\"title\": \"科幻未來\", \"url\": \"\/list\/672\/{{page==1?'':'page'+page+'\/'}}\", \"style\": {\"layout_flexGrow\": 1}}, {\"title\": \"懸疑靈異\", \"url\": \"\/list\/673\/{{page==1?'':'page'+page+'\/'}}\", \"style\": {\"layout_flexGrow\": 1}}, {\"title\": \"古代言情\", \"url\": \"\/list\/674\/{{page==1?'':'page'+page+'\/'}}\", \"style\": {\"layout_flexGrow\": 1}}, {\"title\": \"現代言情\", \"url\": \"\/list\/675\/{{page==1?'':'page'+page+'\/'}}\", \"style\": {\"layout_flexGrow\": 1}}, {\"title\": \"完結小說\", \"url\": \"\/list\/finish2\/{{page==1?'':'page'+page+'\/'}}\", \"style\": {\"layout_flexGrow\": 1}}]","header":"{\"User-Agent\": \"Mozilla\/5.0 (Linux; Android 14; Mobile) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/132.0.0.0 Mobile Safari\/537.36\", \"Referer\": \"https:\/\/www.85novel.com\/\", \"Accept\": \"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8\", \"Accept-Language\": \"zh-TW,zh;q=0.9,zh-CN;q=0.8,en;q=0.7\"}","lastUpdateTime":"1779624954527","respondTime":180000,"ruleBookInfo":{"author":"{{book.author}}","coverUrl":"{{book.coverUrl}}","intro":"{{book.intro}}","kind":"{{book.kind}}","lastChapter":"li.flex.items-center.0@a@text","name":"{{book.name}}","wordCount":".text-base-700[-1]@span.0@text"},"ruleContent":{"content":"div.flex.flex-col.gap-5.pb-12.relative@html@js:java.t2s(result)","replaceRegex":"##這章太精彩了，一定要好評！|85小說網是最好的小說網|©\\s*2013-2026[\\s\\S]*","title":"title@text##\\s*-\\s*85小說網.*|最新免費章節線上看.*"},"ruleExplore":{"author":"p.author span.0@text##\\s*著\\s*$|作者[:：]?","bookList":".book-content-list li","bookUrl":"h4 a@href##$##,{\"webView\":true}","coverUrl":"img@data-original","intro":"p.intro@text","kind":"p.author@text##作者[:：]?|\\s*著\\s*","lastChapter":"p.update a@text","name":"h4 a@text"},"ruleSearch":{"author":"span.0@text##^\\s*✍\\s*|\\s*著\\s*$","bookList":"<js>\nif (result.match(\/Just a moment...|Checking your browser|cloudflare\/i)) {\n    var xb = baseUrl + \",\" + JSON.stringify({\n        \"headers\": {\n            \"User-Agent\": \"Mozilla\/5.0 (Linux; Android 14; Mobile) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/132.0.0.0 Mobile Safari\/537.36\"\n        }\n    });\n    java.startBrowserAwait(xb, \"验证\");\n    result = java.ajax(xb);\n}\nresult\n<\/js>\ndiv.flex.flex-col.gap-2","bookUrl":"a.0@href##$##,{\"webView\":true}","coverUrl":"img@src","intro":"p@text","kind":"span[2:3]@text","lastChapter":"a.-1@text","name":"h3@text","wordCount":"span.4@text"},"ruleToc":{"chapterList":"<js>\nvar datax = null;\nvar allChapters = [];\nvar finalJsonOutput = null;\nvar inputString = baseUrl;\nvar parts = inputString.split(',');\nvar url = parts[0].trim();\n\ntry {\n    var xDataRegex = \/x-data=\"[^\"]*Login\\(\\d+,\\s*'([^']+)'\/;\n    var match = result.match(xDataRegex);\n    if (match && match[1]) {\n        datax = match[1];\n    } else {\n        java.log(\"未能从源码中匹配并提取到 x-data token\");\n        throw new Error(\"XSRF token not found\");\n    }\n\n    var urlWithXsrf = url + \"?_xsrf=\" + encodeURIComponent(datax);\n    var cookie = \"85_ID=\" + java.getCookie(url, \"85_ID\");\n\n    var baseHeaders = {\n        \"User-Agent\": \"Mozilla\/5.0 (Linux; Android 14; Mobile) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/132.0.0.0 Mobile Safari\/537.36\",\n        \"Content-Type\": \"application\/json;charset=UTF-8\",\n        \"Referer\": url,\n        \"Accept\": \"application\/json, text\/plain, *\/*\",\n        \"Cookie\": cookie\n    };\n\n    var slices = [];\n    var selectContentRegex = \/<select class=\"[^\"]*select-primary[^\"]*\"[^>]*>([\\s\\S]*?)<\\\/select>\/;\n    var selectMatch = result.match(selectContentRegex);\n    if (selectMatch && selectMatch[1]) {\n        var optionsHtml = selectMatch[1];\n        var sliceRegex = \/(\\d+)\\s*~\\s*(\\d+)\/g;\n        var sliceMatch;\n        while ((sliceMatch = sliceRegex.exec(optionsHtml)) !== null) {\n            var start = parseInt(sliceMatch[1], 10);\n            var end = parseInt(sliceMatch[2], 10);\n            if (!isNaN(start) && !isNaN(end)) {\n                slices.push([start, end]);\n            }\n        }\n    }\n\n    if (slices.length === 0) {\n        slices = [[1, 200]];\n    }\n\n    for (var i = 0; i < slices.length; i++) {\n        var currentSlice = slices[i];\n        var maxAttempts = 3;\n        var success = false;\n\n        for (var attempt = 1; attempt <= maxAttempts; attempt++) {\n            try {\n                var bodyPayload = {\n                    \"action\": \"chapters\",\n                    \"slice\": currentSlice\n                };\n                var op = {\n                    \"body\": JSON.stringify(bodyPayload),\n                    \"method\": \"post\",\n                    \"headers\": baseHeaders\n                };\n                var requestString = urlWithXsrf + \",\" + JSON.stringify(op);\n                var jsonString = java.ajax(requestString);\n\n                if (jsonString && (jsonString.trim().startsWith(\"{\") || jsonString.trim().startsWith(\"[\"))) {\n                    var jsonObject = JSON.parse(jsonString);\n                    if (jsonObject && jsonObject.result && Array.isArray(jsonObject.result.chapters)) {\n                        allChapters = allChapters.concat(jsonObject.result.chapters);\n                        success = true;\n                        break;\n                    }\n                }\n            } catch (e) {\n                java.log(\"获取目录分段失败: \" + currentSlice.join(\"~\") + \" attempt=\" + attempt + \" err=\" + e);\n            }\n\n            if (!success && attempt < maxAttempts) {\n                Packages.java.lang.Thread.sleep(3000);\n            }\n        }\n\n        if (i < slices.length - 1) {\n            Packages.java.lang.Thread.sleep(1500);\n        }\n    }\n\n    finalJsonOutput = JSON.stringify({\n        \"code\": 0,\n        \"result\": {\n            \"code\": 1,\n            \"chapters\": allChapters\n        }\n    });\n\n} catch (e) {\n    java.log(\"目录 JS 顶层错误: \" + e);\n    finalJsonOutput = JSON.stringify({\n        \"code\": 0,\n        \"result\": {\n            \"code\": 1,\n            \"chapters\": []\n        }\n    });\n}\n\nresult = finalJsonOutput;\n<\/js>\n$.result.chapters","chapterName":"$.ChapterName","chapterUrl":"$.ChapterUrl##(.*?)\/(.*?)##https:\/\/www.85novel.com\/book\/$1\/$2"},"searchUrl":"https:\/\/www.85novel.com\/search?k={{key}}&page={{page}}","weight":0}]