UNPKG

rsshub

Version:
166 lines (164 loc) 7.18 kB
import { n as init_esm_shims, t as __dirname } from "./esm-shims-CzJ_djXG.mjs"; import "./config-C37vj7VH.mjs"; import "./dist-BInvbO1W.mjs"; import "./logger-Czu8UMNd.mjs"; import { t as ofetch_default } from "./ofetch-BIyrKU3Y.mjs"; import { t as parseDate } from "./parse-date-BrP7mxXf.mjs"; import { t as cache_default } from "./cache-Bo__VnGm.mjs"; import { t as art } from "./render-BQo6B4tL.mjs"; import { t as timezone } from "./timezone-D8cuwzTY.mjs"; import path from "node:path"; import * as cheerio from "cheerio"; import CryptoJS from "crypto-js"; //#region lib/routes/sohu/mp.ts init_esm_shims(); const route = { path: "/mp/:xpt", categories: ["new-media"], example: "/sohu/mp/c29odXptdGhnbjZ3NEBzb2h1LmNvbQ==", parameters: { xpt: "搜狐号 xpt ,可在URL中找到或搜狐号 ID" }, radar: [{ source: ["mp.sohu.com/profile"], target: (_params, url) => `/sohu/mp/${new URL(url).searchParams.get("xpt")}` }], name: "最新", maintainers: ["HenryQW"], handler, description: `搜狐号 ID 可以通过以下方式获取: 1. 通过浏览器搜索相关搜狐号 \`果壳 site: mp.sohu.com\`。 2. 通过浏览器控制台执行 \`window.globalConst.mkeyConst_mkey\`,返回的即为搜狐号 ID。` }; function randomString(length = 32) { let r = ""; const e = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678"; const n = 48; for (let i = 0; i < length; i++) r += e.charAt(Math.floor(Math.random() * n)); return r; } const defaultSUV = "1612268936507kas0gk"; function decryptImageUrl(cipherText) { const key = CryptoJS.enc.Utf8.parse("www.sohu.com6666"); return CryptoJS.AES.decrypt(cipherText, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8); } function createAuthToken() { const t = Date.now(); const e = "t" + t; return "v1" + t + CryptoJS.HmacSHA1(e, "439642a904ef43d092d45509cdc4391c").toString(); } function fetchArticle(item) { return cache_default.tryGet(item.link, async () => { const response = await ofetch_default(item.link); const $ = cheerio.load(response); $(".original-title, .lookall-box").remove(); item.author = item.author || $("span[data-role=\"original-link\"] a").text(); item.pubDate = timezone(parseDate($("meta[itemprop=\"dateUpdate\"]").attr("content")), 8); if (/window\.sohu_mp\.article_video/.test($("script").text())) { const videoSrc = $("script").text().match(/\s*url: "(.*?)",/)?.[1]; item.description = art(path.join(__dirname, "templates/video-e51936ec.art"), { poster: $("script").text().match(/cover: "(.*?)",/)?.[1], src: videoSrc, type: videoSrc?.split(".").pop()?.toLowerCase() }); } else { const article = $("#mp-editor"); article.find("#backsohucom, p[data-role=\"editor-name\"]").each((i, e) => { $(e).remove(); }); article.find("img").each((_, e) => { const $e = $(e); if ($e.attr("data-src") && !$e.attr("src")) { $e.attr("src", decryptImageUrl($e.attr("data-src"))); $e.removeAttr("data-src"); } }); item.description = article.html(); } return item; }); } async function handler(ctx) { const xpt = ctx.req.param("xpt"); if (/^\d+$/.test(xpt)) return legacyIdHandler(ctx); const pageResponse = await ofetch_default.raw("https://mp.sohu.com/profile", { query: { xpt } }); const suv = pageResponse.headers?.getSetCookie().find((e) => e.startsWith("SUV"))?.split(";")[0]; const $ = cheerio.load(pageResponse._data); const CBDRenderConst = JSON.parse($("script:contains(\"CBDRenderConst\")").text().trim().match(/CBDRenderConst\s=\s(.*)/)?.[1] || "{}"); const contentData = JSON.parse($("script:contains(\"contentData\")").toArray().map((e) => $(e).text().match(/contentData = (.*)/)?.[1]).toSorted((a, b) => b.length - a.length)[0] || "{}"); const blockRenderData = JSON.parse($("script:contains(\"column_2_text\")").text().match(/({.*})/)?.[1]); const renderData = blockRenderData[Object.keys(blockRenderData).find((e) => e.startsWith("FeedSlideloadAuthor"))]; const briefIntroductionCard = blockRenderData[Object.keys(blockRenderData).find((e) => e.startsWith("BriefIntroductionCard"))].param.data.list[0]; const globalConst = JSON.parse($("script:contains(\"globalConst\")").text().match(/globalConst\s=\s(.*)/)?.[1] || "{}"); const originalRequest = JSON.parse($("script:contains(\"originalRequest\")").text().match(/originalRequest\s=\s(.*)/)?.[1] || "{}"); const list = (await ofetch_default("https://odin.sohu.com/odin/api/blockdata", { method: "POST", headers: { Cookie: Object.entries({ SUV: suv, itssohu: "true", reqtype: "pc", t: Date.now() }).map(([key, value]) => `${key}=${value}`).join("; ") }, body: { pvId: CBDRenderConst.COMMONCONFIG.pvId || `${Date.now()}_${randomString(7)}`, pageId: `${Date.now()}_${defaultSUV?.slice(0, -5)}_${randomString(3)}`, mainContent: { productType: contentData.businessType || "13", productId: contentData.id || "324", secureScore: contentData.secureScore || "5", categoryId: contentData.categoryId || "47", adTags: contentData.adTags || "11111111", authorId: contentData.account.id || 121135924 }, resourceList: [{ tplCompKey: renderData.param.data2.reqParam.tplCompKey || "FeedSlideloadAuthor_2_0_pc_1655965929143_data2", isServerRender: renderData.param.data2.reqParam.isServerRender || false, isSingleAd: renderData.param.data2.reqParam.isSingleAd || false, configSource: renderData.param.data2.reqParam.configSource || "mp", content: { productId: renderData.param.data2.reqParam.content.productId || "325", productType: renderData.param.data2.reqParam.content.productType || "13", size: 20, pro: renderData.param.pro || "0,1,3,4,5", feedType: renderData.param.feedType || "XTOPIC_SYNTHETICAL", view: "operateFeedMode", innerTag: renderData.param.data2.reqParam.content.innerTag || "work", spm: renderData.param.data2.reqParam.content.spm || "smpc.channel_248.block3_308_hHsK47_2_fd", page: 1, requestId: `${Date.now()}${randomString(7)}_${contentData.id}` }, adInfo: {}, context: { mkey: globalConst.mkeyConst_mkey } }], asId: createAuthToken() } })).data[renderData.param.data2.reqParam.tplCompKey].list.map((item) => ({ title: item.title, description: item.brief, link: `https://www.sohu.com/a/${item.id}_${globalConst.mkeyConst_mkey}` })); const items = await Promise.all(list.map((e) => fetchArticle(e))); return { title: `搜狐号 - ${globalConst.title}`, description: briefIntroductionCard.column_9_text, link: originalRequest.url, image: `https:${briefIntroductionCard.column_2_image}`, item: items }; } async function legacyIdHandler(ctx) { const id = ctx.req.param("xpt"); const list = (await ofetch_default(`https://v2.sohu.com/author-page-api/author-articles/pc/${id}`)).data.pcArticleVOS.map((item) => ({ title: item.title, link: item.link.startsWith("http") ? item.link : `https://${item.link}`, pubDate: parseDate(item.publicTime) })); const items = await Promise.all(list.map((e) => fetchArticle(e))); return { title: `搜狐号 - ${id}`, item: items }; } //#endregion export { route };