Aff
https://www.asianfanfics.com
zqy2021 (12437)3天前
魔法,同人,zqy2021
{
"bookSourceComment": "魔法,同人,zqy2021",
"bookSourceName": "Aff",
"bookSourceType": 0,
"bookSourceUrl": "https:\/\/www.asianfanfics.com",
"bookUrlPattern": "(https?:\/\/)?(www\\.)?asianfanfics\\.com",
"concurrentRate": "2000",
"customButton": false,
"customOrder": -1,
"enabled": true,
"enabledCookieJar": true,
"enabledExplore": true,
"eventListener": true,
"exploreUrl": "我的订阅::https:\/\/www.asianfanfics.com\/account\/subscriptions,{\"webView\":true}\n最新更新::https:\/\/www.asianfanfics.com\/browse?page={{page}},{\"webView\":true}\n最新发布::https:\/\/www.asianfanfics.com\/browse\/newest?page={{page}},{\"webView\":true}\n热门趋势::https:\/\/www.asianfanfics.com\/browse\/trending?page={{page}},{\"webView\":true}\n已完成::https:\/\/www.asianfanfics.com\/browse\/completed?page={{page}},{\"webView\":true}\n短篇::https:\/\/www.asianfanfics.com\/browse\/one-shots?page={{page}},{\"webView\":true}\n系列::https:\/\/www.asianfanfics.com\/browse\/series?page={{page}},{\"webView\":true}\n推荐::https:\/\/www.asianfanfics.com\/browse\/featured?page={{page}},{\"webView\":true}\n浏览量::https:\/\/www.asianfanfics.com\/browse\/views?page={{page}},{\"webView\":true}\n收藏数::https:\/\/www.asianfanfics.com\/browse\/favorited?page={{page}},{\"webView\":true}\n评论数::https:\/\/www.asianfanfics.com\/browse\/commented?page={{page}},{\"webView\":true}",
"header": "{\"User-Agent\":\"Mozilla\/5.0 (Linux; Android 13; Pixel 7) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/120.0.0.0 Mobile Safari\/537.36\",\"Accept\":\"text\/html,application\/xhtml+xml,application\/xml;q=0.9,*\/*;q=0.8\",\"Accept-Language\":\"en-US,en;q=0.9\"}",
"lastUpdateTime": "1786556318945",
"loginCheckJs": "var resultUrl = result.url();\nvar resultCode = result.code();\nvar resultBoDy = result.body();\nif (\/Just a moment|_cf_chl_opt|challenges.cloudflare.com|Enable JavaScript and cookies\/gi.test(resultBoDy) && resultCode >= 403) {\n if (key) {\n url = baseUrl + java.ruleUrl;\n }\n cookie.removeCookie(baseUrl);\n result = java.startBrowserAwait(resultUrl, \"Cloudflare验证\", false);\n if (key) {\n url = org.jsoup.Jsoup.parse(result.body()).select('meta[property=\"og:url\"]').attr(\"content\") || url;\n }\n}\nresult;",
"loginUi": "[{\"name\":\"提示\",\"type\":\"button\",\"action\":\"java.toast('点击下方按钮在浏览器中登录')\"},{\"name\":\"登录\",\"type\":\"button\",\"action\":\"login()\"}]",
"loginUrl": "function login() {\n java.startBrowserAwait(\"https:\/\/www.asianfanfics.com\/login\", \"登录 Asianfanfics\");\n try {\n var home = java.ajax(\"https:\/\/www.asianfanfics.com\/\");\n if (\/logout|Log out\/i.test(home)) {\n java.toast(\"登录成功\");\n } else {\n java.toast(\"登录可能未成功,请重试\");\n }\n } catch (e) {\n java.toast(\"登录完成,如未成功请重试\");\n }\n}",
"respondTime": 180000,
"ruleBookInfo": {
"author": "a.hover\\:underline.dark\\:text-indigo-300.font-semibold.text-indigo-600@text",
"intro": "@css:main@html<js>\nvar src = String(result);\nvar doc = org.jsoup.Jsoup.parse(src, baseUrl);\nvar descLines = [];\nvar descPs = doc.select('#story-description p');\nfor (var i = 0; i < descPs.size(); i++) {\n var t = String(descPs.get(i).text()).replace(\/\\u00a0| \/g, ' ').trim();\n if (t) descLines.push(t);\n}\nvar fwLines = [];\nvar fwPs = doc.select('#story-foreword p');\nfor (var j = 0; j < fwPs.size(); j++) {\n var ft = String(fwPs.get(j).text()).replace(\/\\u00a0| \/g, ' ').trim();\n if (ft) fwLines.push(ft);\n}\nvar desc = descLines.join('\\n');\nvar foreword = fwLines.join('\\n');\ndesc + (foreword ? '\\n\\u3000\\nForeword\\n' + foreword : '')\n<\/js>",
"kind": ".mt-2@text",
"lastChapter": "p.mt-2.text-xs.text-muted > time@text",
"name": "h1.sm\\:text-3xl.mt-0.text-2xl.font-bold.leading-tight.text-heading@text",
"wordCount": "div.space-y-2.px-3.pb-3.text-sm.text-muted > p@text"
},
"ruleContent": {
"callBackJs": "var m = String(book.bookUrl).match(\/story\\\/view\\\/(\\d+)\/);\nif (m) {\n var storyId = m[1];\n if (event == \"addBookShelf\" || event == \"delBookShelf\") {\n try {\n var storyPageUrl = \"https:\/\/www.asianfanfics.com\/story\/view\/\" + storyId;\n var storyHtml = java.ajax(storyPageUrl + ',{\"method\":\"GET\"}');\n java.log(\"页面长度: \" + String(storyHtml).length);\n var doc = org.jsoup.Jsoup.parse(storyHtml, storyPageUrl);\n var csrfToken = \"\";\n var targetUrl = \"\";\n var targetMethod = \"\";\n var foundSubPost = false;\n var foundSubDelete = false;\n var els = doc.select(\"[hx-post], [hx-delete]\");\n var btnLog = [];\n for (var i = 0; i < els.size(); i++) {\n var el = els.get(i);\n var hp = String(el.attr(\"hx-post\"));\n var hd = String(el.attr(\"hx-delete\"));\n var url = hp || hd;\n var method = hp ? \"POST\" : \"DELETE\";\n if (!url) continue;\n btnLog.push(method + \" \" + url);\n if (\/subscribe\/i.test(url) && !\/unsubscribe\/i.test(url)) {\n if (method == \"POST\") foundSubPost = true;\n if (method == \"DELETE\") foundSubDelete = true;\n }\n var match = false;\n if (event == \"addBookShelf\" && method == \"POST\" && \/subscribe\/i.test(url) && !\/unsubscribe\/i.test(url)) match = true;\n if (event == \"delBookShelf\" && method == \"DELETE\" && \/subscribe\/i.test(url)) match = true;\n if (match) {\n targetUrl = url;\n targetMethod = method;\n var hh = String(el.attr(\"hx-headers\")).replace(\/"\/g, '\"').replace(\/"\/g, '\"');\n if (hh) {\n var cm = hh.match(\/x-csrf-token[\"']?\\s*:\\s*[\"']([^\"']+)\/i);\n if (cm) csrfToken = cm[1];\n }\n }\n }\n if (!csrfToken) {\n var cleanHtml = String(storyHtml).replace(\/"\/g, '\"').replace(\/"\/g, '\"');\n var hc = cleanHtml.match(\/x-csrf-token[\"']?\\s*:\\s*[\"']([^\"']+)\/i);\n if (hc) csrfToken = hc[1];\n }\n java.log(\"按钮列表: \" + btnLog.join(\" | \"));\n if (targetUrl && targetUrl.indexOf(\"http\") != 0) {\n targetUrl = \"https:\/\/www.asianfanfics.com\" + (targetUrl.charAt(0) == \"\/\" ? \"\" : \"\/\") + targetUrl;\n }\n java.log(\"目标: \" + targetMethod + \" \" + targetUrl + \" CSRF:\" + csrfToken.length + \" token:\" + csrfToken.substring(0, 20));\n if (targetUrl) {\n var headerObj = {\n \"HX-Request\": \"true\",\n \"HX-Trigger\": \"subscribeBtn\",\n \"HX-Target\": \"story-vote-actions\",\n \"HX-Swap\": \"none\",\n \"HX-Current-URL\": storyPageUrl,\n \"X-Requested-With\": \"XMLHttpRequest\",\n \"Referer\": storyPageUrl,\n \"Origin\": \"https:\/\/www.asianfanfics.com\"\n };\n if (csrfToken) headerObj[\"X-CSRF-Token\"] = csrfToken;\n var response = \"\";\n var statusCode = 0;\n var headerMap = new Packages.java.util.HashMap();\n for (var k in headerObj) headerMap.put(k, headerObj[k]);\n if (targetMethod == \"POST\") {\n headerMap.put(\"Content-Type\", \"application\/x-www-form-urlencoded\");\n var resp = java.post(targetUrl, \"\", headerMap);\n statusCode = resp.statusCode();\n response = resp.body();\n } else {\n var cookieStr = String(cookie.getCookie(targetUrl));\n java.log(\"Cookie长度: \" + cookieStr.length);\n var jsoupConn = org.jsoup.Jsoup.connect(targetUrl)\n .method(org.jsoup.Connection.Method.DELETE)\n .header(\"Cookie\", cookieStr)\n .header(\"HX-Request\", \"true\")\n .header(\"HX-Trigger\", \"subscribeBtn\")\n .header(\"HX-Target\", \"story-vote-actions\")\n .header(\"HX-Swap\", \"none\")\n .header(\"HX-Current-URL\", storyPageUrl)\n .header(\"X-CSRF-Token\", csrfToken)\n .header(\"X-Requested-With\", \"XMLHttpRequest\")\n .header(\"Referer\", storyPageUrl)\n .header(\"Origin\", \"https:\/\/www.asianfanfics.com\")\n .header(\"User-Agent\", \"Mozilla\/5.0 (Linux; Android 13; Pixel 7) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/120.0.0.0 Mobile Safari\/537.36\")\n .ignoreContentType(true)\n .ignoreHttpErrors(true);\n var resp2 = jsoupConn.execute();\n statusCode = resp2.statusCode();\n response = resp2.body();\n }\n java.log(\"状态: \" + statusCode + \" 长度: \" + String(response).length);\n java.log(\"结果: \" + String(response).substring(0, 1000));\n var success = false;\n if (statusCode == 200 || statusCode == 204) {\n if (event == \"addBookShelf\") {\n success = \/hx-delete\/i.test(response);\n } else {\n var hasSubDelete = \/hx-delete=\"[^\"]*subscribe\/i.test(response);\n success = !hasSubDelete;\n }\n }\n java.log(\"成功: \" + success);\n if (success) {\n java.toast(event == \"addBookShelf\" ? \"已订阅,请下拉刷新正文\" : \"已取消订阅\");\n } else {\n java.toast(event == \"addBookShelf\" ? \"订阅未成功,请重试\" : \"取消订阅未成功,请重试\");\n }\n } else {\n if (event == \"addBookShelf\" && foundSubDelete) {\n java.toast(\"已订阅,无需重复订阅\");\n } else if (event == \"delBookShelf\" && foundSubPost && !foundSubDelete) {\n java.toast(\"未订阅,无需取消\");\n } else {\n java.toast(\"未找到订阅按钮,请检查登录状态\");\n }\n }\n } catch (e) {\n java.log(\"失败: \" + e);\n java.toast(\"失败: \" + e);\n }\n }\n}",
"content": "@css:p@textNodes<js>\nvar lines = String(result).split('\\n');\nvar out = [];\nfor (var i = 0; i < lines.length; i++) {\n var t = lines[i].replace(\/\\u00a0| \/g, ' ').trim();\n if (t) out.push(t);\n}\nout.join('\\n')\n<\/js>",
"title": "h1.sm\\:text-3xl.mt-0.text-2xl.font-bold.leading-tight.text-heading@text",
"webJs": "(() => {\n const selector = 'div#user-submitted-body';\n if (!window.__legado_scrolled) {\n window.scrollTo(0, document.body.scrollHeight);\n window.__legado_scrolled = true;\n return null;\n }\n const el = document.querySelector(selector);\n if (!el) return null;\n const ps = el.querySelectorAll('p');\n if (ps.length === 0) return null;\n const text = el.innerText || '';\n const placeholderPattern = \/couldn't be loaded|Refresh the page|请稍候\/i;\n if (placeholderPattern.test(text) && ps.length < 3) return null;\n return el.innerHTML;\n})();"
},
"ruleExplore": {
"author": "a[href^=\/profile\/u\/]@text",
"bookList": "div.border-b.border-border",
"bookUrl": "h3 a@href<js>String(result)+',{\"webView\":true}'<\/js>",
"intro": "p.line-clamp-2@text",
"kind": "a[href^=\/browse\/tag\/]@text",
"lastChapter": "time@text",
"name": "h3 a@text",
"wordCount": "p.text-slate-500@text"
},
"ruleSearch": {
"author": "a[href^=\/profile\/u\/]@text",
"bookList": "#search-results div.border-b.border-border",
"bookUrl": "h3 a@href<js>String(result)+',{\"webView\":true}'<\/js>",
"checkKeyWord": "love",
"intro": "p.line-clamp-2@text",
"kind": "a[href^=\/browse\/tag\/]@text",
"lastChapter": "time@text",
"name": "h3 a@text",
"wordCount": "p.text-slate-500@text"
},
"ruleToc": {
"chapterList": "div.group.relative.flex.items-stretch",
"chapterName": "span.truncate@text",
"chapterUrl": "a@href<js>String(result)+',{\"webView\":true}'<\/js>"
},
"searchUrl": "https:\/\/www.asianfanfics.com\/browse\/search?q={{key}}&page={{page}},{\"webView\":true}",
"weight": 0
}