UNPKG

rsshub

Version:
111 lines (110 loc) 4.58 kB
import { t as config } from "./config-CCmw1BNE.mjs"; import { t as cache_default } from "./cache-BkqOokyU.mjs"; import { t as got_default } from "./got-BTowW50G.mjs"; import { t as ConfigNotFoundError } from "./config-not-found-fQ5mxvDU.mjs"; import { t as getPlaywrightPage } from "./playwright-o20DiLNh.mjs"; import { createHash } from "node:crypto"; import { Cookie } from "tough-cookie"; //#region lib/routes/baidu/tieba/common.ts /** * 解析百度 cookie 字符串为 Playwright 可用的 cookie 对象数组 * 正确处理包含 '=' 的 cookie 值 */ function parseBaiduCookies(cookieStr) { return cookieStr.split(";").map((c) => Cookie.parse(c.trim())).filter((c) => Boolean(c?.key)).map((c) => ({ name: c.key, value: c.value, domain: ".tieba.baidu.com", path: "/" })); } /** * 检查 HTML 内容是否包含百度安全验证页面 */ function checkSecurityVerification(html) { if (html.includes("安全验证") || html.includes("百度安全验证")) throw new Error("Baidu security verification required. The cookie may be expired or invalid. Please update your BAIDU_COOKIE."); } /** * 使用 Playwright 获取贴吧页面内容 * 包含统一的 cookie 设置、安全验证检查和缓存逻辑 * 带有重试机制处理瞬态错误 */ async function getTiebaPageContent(url, cacheKey, options = {}) { const cookie = config.baidu.cookie; if (!cookie) throw new ConfigNotFoundError("Baidu Tieba RSS is disabled due to the lack of <a href=\"https://docs.rsshub.app/deploy/config#baidu\">BAIDU_COOKIE</a>"); const cookies = parseBaiduCookies(cookie); const { waitForSelector = ".thread-card-wrapper, .virtual-list-item, .thread-content-box, .thread-card", timeout = 3e3, retries = 3 } = options; return await cache_default.tryGet(cacheKey, async () => { let lastError; for (let attempt = 0; attempt < retries; attempt++) { const { page, destroy } = await getPlaywrightPage(url, { onBeforeLoad: async (page) => { if (cookies.length > 0) await page.context().addCookies(cookies); }, gotoConfig: { waitUntil: "domcontentloaded" } }); try { await new Promise((resolve) => setTimeout(resolve, 2e3)); try { await page.waitForSelector(waitForSelector, { timeout }); } catch {} const html = await page.content(); checkSecurityVerification(html); return html; } catch (error) { lastError = error; if (attempt === retries - 1) throw lastError; await new Promise((resolve) => setTimeout(resolve, 1e3 * (attempt + 1))); } finally { await destroy(); } } throw lastError || /* @__PURE__ */ new Error("Failed to fetch page content"); }, config.cache.routeExpire, false); } /** * 规范化 URL 为绝对地址 */ function normalizeUrl(href, base = "https://tieba.baidu.com") { if (!href) return ""; if (href.startsWith("http")) return href; return `${base}${href.startsWith("/") ? href : `/${href}`}`; } /** * 通过 /c/f/frs/page API 获取贴吧帖子列表 * 使用贴吧客户端签名认证,无需 Puppeteer */ const TIEBA_CLIENT_SECRET = "tiebaclient!!!"; function computeSign(params) { const raw = Object.keys(params).toSorted().map((key) => `${key}=${params[key]}`).join("") + TIEBA_CLIENT_SECRET; return createHash("md5").update(raw).digest("hex"); } async function getTiebaForumData(params) { const cookie = config.baidu.cookie; if (!cookie) throw new ConfigNotFoundError("Baidu Tieba RSS is disabled due to the lack of <a href=\"https://docs.rsshub.app/deploy/config#baidu\">BAIDU_COOKIE</a>"); const bduss = cookie.match(/BDUSS=([^;]+)/)?.[1] || ""; if (!bduss) throw new ConfigNotFoundError("BAIDU_COOKIE must contain BDUSS. Please check your cookie configuration."); const apiParams = { _client_id: "wappc_1234567890123_456", _client_type: "2", _client_version: "12.20.1.0", _phone_imei: "000000000000000", from: "tieba", kw: params.kw, rn: "30", pn: "1", BDUSS: bduss }; if (params.isGood) apiParams.is_good = "1"; if (params.cid && params.cid !== "0") apiParams.cid = params.cid; if (params.sortBy === "replied") apiParams.sort_type = "1"; apiParams.sign = computeSign(apiParams); const url = "https://tieba.baidu.com/c/f/frs/page"; const cacheKey = `tieba:api:forum:${params.kw}:${params.cid || "0"}:${params.sortBy || "created"}`; return await cache_default.tryGet(cacheKey, async () => { const { data: response } = await got_default.post(url, { form: apiParams }); return response; }, config.cache.routeExpire, false); } //#endregion export { getTiebaPageContent as n, normalizeUrl as r, getTiebaForumData as t };