rsshub
Version:
Make RSS Great Again!
166 lines (164 loc) • 7.18 kB
JavaScript
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 };