UNPKG

rsshub

Version:
73 lines (72 loc) 2.78 kB
import { t as rofetch } from "./ofetch-W1aeTHCo.mjs"; import { t as parseDate } from "./parse-date-CjhZE69i.mjs"; import { t as cache_default } from "./cache-CiDoUSLo.mjs"; import { t as InvalidParameterError } from "./invalid-parameter-CGxhjomn.mjs"; import { s as solveWafChallenge } from "./utils-BImtW9k-.mjs"; import { load } from "cheerio"; //#region lib/routes/etoland/board.ts const route = { path: "/:bo_table", categories: ["bbs"], example: "/etoland/star01", parameters: { bo_table: "板块 id,可在板块 URL 找到" }, features: { antiCrawler: true }, radar: [{ source: ["etoland.co.kr/b/:bo_table/list"], target: "/:bo_table" }], name: "主题贴", maintainers: ["mengx8"], handler }; const baseUrl = "https://etoland.co.kr"; const getWafToken = (url) => cache_default.tryGet("etoland:_waftokenid", async () => { const challengePage = await rofetch(url); const challenge = /atob\('([\d+/=A-Za-z]{80,})'\)/.exec(challengePage)[1]; return (await rofetch.raw(url, { headers: { cookie: `_wafchallengeid=${solveWafChallenge(challenge)};` }, redirect: "manual" })).headers.getSetCookie().map((c) => c.split(";", 1)[0]).find((c) => c.startsWith("_waftokenid=")); }, 600, false); const extractArticleList = ($) => { const chunk = /self\.__next_f\.push\(\[\d+,(".*")\]\)/s.exec($("script:contains(\"articleList\")").text()); if (!chunk) throw new InvalidParameterError("This board is not supported"); const stream = JSON.parse(chunk[1]); const start = stream.indexOf("\"articleList\":") + 14; let depth = 0; let inString = false; let escaped = false; for (let i = start; i < stream.length; i++) { const char = stream[i]; if (escaped) escaped = false; else if (char === "\\") escaped = true; else if (char === "\"") inString = !inString; else if (!inString) { if (char === "[") depth++; else if (char === "]" && --depth === 0) return JSON.parse(stream.slice(start, i + 1)); } } throw new Error("Failed to locate articleList in the page payload"); }; async function handler(ctx) { const { bo_table } = ctx.req.param(); const link = `${baseUrl}/b/${bo_table}/list`; const response = await rofetch(link, { headers: { cookie: await getWafToken(link) } }); const articles = extractArticleList(load(response)); const items = articles.slice(0, ctx.req.query("limit") ? Number(ctx.req.query("limit")) : 25).map((article) => ({ title: article.subject, link: `${baseUrl}/b/${article.boTable}/view/${encodeURIComponent(article.slug)}`, author: article.member.nickname, category: article.category, pubDate: parseDate(article.writeDateTimestamp), comments: article.commentCount })); return { title: `eTOLAND - ${articles[0].boTableName}`, link, language: "ko", item: items }; } //#endregion export { route };