九九藏书网
https://www.99csw.com
sf-gitee (12782)03/23 21:00
v6,修复了cf验证的问题。
{
"bookSourceComment": "先在搜索页点击登陆完成Cloudflare验证。",
"bookSourceGroup": "",
"bookSourceName": "九九藏书网",
"bookSourceType": 0,
"bookSourceUrl": "https:\/\/www.99csw.com",
"bookUrlPattern": "https?:\/\/(?:www|read)\\.99csw\\.com\/book\/\\d+(?:\/(?:index\\.htm|index\\.html|\\d+\\.htm|\\d+\\.html)?)?",
"customOrder": 1,
"enabled": true,
"enabledCookieJar": true,
"enabledExplore": false,
"exploreUrl": "",
"header": "{\n \"User-Agent\": \"Mozilla\/5.0 (Linux; Android 14; Pixel 7) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/134.0.0.0 Mobile Safari\/537.36\",\n \"Accept-Language\": \"zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7\",\n \"Referer\": \"https:\/\/www.99csw.com\/index.php\"\n}",
"lastUpdateTime": "1774270846550",
"loginUrl": "https:\/\/www.99csw.com\/",
"respondTime": 180000,
"ruleBookInfo": {
"bookInfoInit": "<js>\n(function(){\n function needVerify(s){\n s = String(s || '');\n return \/Just a moment|Cloudflare|challenge-platform|cf-browser-verification|security check|验证您是真人\/i.test(s);\n }\n function trim(s){\n return s ? String(s).replace(\/\\s+\/g, ' ').replace(\/^\\s+|\\s+$\/g, '') : '';\n }\n function text(doc, sel){\n var e = doc.select(sel).first();\n return e ? trim(e.text()) : '';\n }\n function attr(doc, sel, name){\n var e = doc.select(sel).first();\n return e ? trim(e.attr('abs:' + name)) : '';\n }\n\n var html = String(result || '');\n if (needVerify(html)) {\n try { cookie.removeCookie(source.getKey()); } catch(e) {}\n html = java.startBrowserAwait(baseUrl, 'CF验证').body();\n }\n\n var doc = org.jsoup.Jsoup.parse(html, baseUrl);\n var introNode = doc.select('#book_info .intro').first();\n var intro = '';\n if (introNode) {\n introNode.select('a').unwrap();\n intro = trim(introNode.text());\n }\n\n var kind = text(doc, '.title99.title a[href*=book\/index.php?type]');\n var tags = [];\n var tagEls = doc.select('#book_info h4:eq(1) a');\n for (var i = 0; i < tagEls.size(); i++) {\n var t = trim(tagEls.get(i).text());\n if (t && t != kind) tags.push(t);\n }\n if (tags.length > 0) {\n kind = kind ? (kind + ',' + tags.join(',')) : tags.join(',');\n }\n\n var count = doc.select('#dir dd').size();\n return {\n n: text(doc, '#book_info h2'),\n a: text(doc, '#author_box h4') || text(doc, '#book_info h4:eq(0) a'),\n k: kind,\n w: count > 0 ? (count + '章') : '',\n l: text(doc, '#dir dd:last-child a'),\n i: intro,\n c: attr(doc, '#book_info img', 'src'),\n t: String(baseUrl)\n };\n})()\n<\/js>",
"canReName": true,
"author": "a",
"coverUrl": "c",
"intro": "i",
"kind": "k",
"lastChapter": "l",
"name": "n",
"tocUrl": "t",
"wordCount": "w"
},
"ruleContent": {
"content": "<js>\n(function(){\n function needVerify(s){\n s = String(s || '');\n return \/Just a moment|Cloudflare|challenge-platform|cf-browser-verification|security check|验证您是真人\/i.test(s);\n }\n function esc(s){\n return String(s || '')\n .replace(\/&\/g, '&')\n .replace(\/<\/g, '<')\n .replace(\/>\/g, '>');\n }\n function trim(s){\n return s ? String(s).replace(\/^\\s+|\\s+$\/g, '') : '';\n }\n function cleanText(s){\n return String(s || '')\n .replace(\/https?:\\\/\\\/(?:read\\.)?99csw\\.com\/ig, '')\n .replace(\/99lib\\.net\/ig, '')\n .replace(\/99csw\\.com\/ig, '')\n .replace(\/九九藏书网|九九藏書網\/g, '')\n .replace(\/九\\*九\\*藏\\*书\\*网|九\\*九\\*藏\\*書\\*網\/ig, '')\n .replace(\/\\u00a0\/g, ' ')\n .replace(\/[ \\t\\x0B\\f\\r]+\/g, ' ')\n .replace(\/\\n{3,}\/g, '\\n\\n')\n .replace(\/^\\s+|\\s+$\/g, '');\n }\n function htmlToTextBlock(html){\n html = String(html || '').replace(\/<br\\s*\\\/?>\/ig, '___LEGADO_BR___');\n var tmp = org.jsoup.Jsoup.parse('<div>' + html + '<\/div>');\n tmp.select('script,style,iframe,noscript').remove();\n var txt = String(tmp.text() || '').replace(\/___LEGADO_BR___\/g, '\\n');\n return cleanText(txt);\n }\n function blockToHtml(text){\n text = cleanText(text);\n if (!text) return '';\n return '<p>' + esc(text).replace(\/\\n\/g, '<br\/>') + '<\/p>';\n }\n\n var html = String(result || '');\n var doc = org.jsoup.Jsoup.parse(html, baseUrl);\n\n var box = doc.select('#content').first();\n if (!box) box = doc.select('div#content').first();\n\n \/\/ 只在正文块缺失时才判断是否是 CF 页面,避免误判\n if (!box) {\n if (needVerify(html)) {\n return '<p>当前章节触发 Cloudflare 校验。请先返回搜索页重新搜索一次,完成验证后再打开本章。<\/p>';\n }\n return '<p>未获取到正文。<\/p>';\n }\n\n box.select('script,style,iframe,noscript,#note_box').remove();\n\n var out = [];\n var children = box.children();\n\n if (children.size() > 0) {\n for (var i = 0; i < children.size(); i++) {\n var el = children.get(i);\n var tag = String(el.tagName() || '').toLowerCase();\n if (tag == 'h2') continue;\n if (String(el.id() || '') == 'note_box') continue;\n\n var imgs = el.select('img');\n var text = htmlToTextBlock(el.html());\n\n if (text) {\n var parts = text.split(\/\\n{2,}\/);\n for (var p = 0; p < parts.length; p++) {\n var part = cleanText(parts[p]);\n if (part) out.push(blockToHtml(part));\n }\n }\n\n if (imgs.size() > 0) {\n for (var j = 0; j < imgs.size(); j++) {\n var src = trim(imgs.get(j).attr('abs:src'));\n if (src) out.push('<p><img src=\"' + src + '\"\/><\/p>');\n }\n }\n }\n }\n\n if (out.length == 0) {\n var raw = String(box.html() || '')\n .replace(\/<h2[\\s\\S]*?<\\\/h2>\/ig, '')\n .replace(\/<span[^>]*id=[\"']note_box[\"'][\\s\\S]*?<\\\/span>\/ig, '');\n var txt = htmlToTextBlock(raw);\n if (txt) {\n var parts2 = txt.split(\/\\n{2,}\/);\n for (var q = 0; q < parts2.length; q++) {\n var part2 = cleanText(parts2[q]);\n if (part2) out.push(blockToHtml(part2));\n }\n }\n }\n\n return out.join('') || '<p>未获取到正文。<\/p>';\n})()\n<\/js>",
"nextContentUrl": "",
"replaceRegex": "",
"imageStyle": "",
"sourceRegex": ""
},
"ruleExplore": {},
"ruleSearch": {
"bookList": "<js>\n(function(){\n function needVerify(s){\n s = String(s || '');\n return \/Just a moment|Cloudflare|challenge-platform|cf-browser-verification|security check|验证您是真人\/i.test(s);\n }\n function trim(s){\n return s ? String(s).replace(\/\\s+\/g, ' ').replace(\/^\\s+|\\s+$\/g, '') : '';\n }\n function parse(html){\n var doc = org.jsoup.Jsoup.parse(String(html || ''), baseUrl);\n var items = doc.select('ul.list_box > li');\n var arr = [];\n for (var i = 0; i < items.size(); i++) {\n var it = items.get(i);\n var author = '';\n var kind = '';\n var h4s = it.select('h4');\n for (var j = 0; j < h4s.size(); j++) {\n var t = trim(h4s.get(j).text());\n if (!author && \/作者[::]\/.test(t)) author = t.replace(\/^.*?作者[::]\\s*\/, '');\n if (!kind && \/分类[::]\/.test(t)) kind = t.replace(\/^.*?分类[::]\\s*\/, '');\n }\n arr.push({\n n: trim(it.select('h2>a').text()),\n a: author || trim(it.select('h4:contains(作者) a').text()),\n k: kind || trim(it.select('h4:contains(分类) a').text()),\n i: trim(it.select('.intro').text()),\n c: trim(it.select('img').attr('abs:src')),\n u: trim(it.select('h2>a').attr('abs:href'))\n });\n }\n return arr;\n }\n\n var html = String(result || '');\n var list = parse(html);\n\n if (list.length == 0 && needVerify(html)) {\n html = java.startBrowserAwait(baseUrl, 'CF验证').body();\n list = parse(html);\n }\n\n return list;\n})()\n<\/js>",
"name": "n",
"author": "a",
"kind": "k",
"wordCount": "",
"lastChapter": "",
"intro": "i",
"coverUrl": "c",
"bookUrl": "u"
},
"ruleToc": {
"chapterList": "@css:#dir > dd",
"chapterName": "a@text",
"chapterUrl": "a@href",
"nextTocUrl": ""
},
"searchUrl": "https:\/\/www.99csw.com\/book\/search.php?s=13139900387823019677&type=%E7%AB%99%E5%86%85&q={{java.encodeURI(key)}},{\"headers\":{\"Referer\":\"https:\/\/www.99csw.com\/index.php\"}}",
"weight": 0
}