rsshub
Version:
Make RSS Great Again!
190 lines (189 loc) • 5.22 kB
JavaScript
import { t as rofetch } from "./ofetch-eUBdfMpp.mjs";
import { t as config } from "./config-Bpyy15zS.mjs";
import { t as parseDate } from "./parse-date-CjhZE69i.mjs";
import { n as generateHeaders, t as PRESETS } from "./header-generator-DACPoxdp.mjs";
import { t as cache_default } from "./cache-CiDoUSLo.mjs";
import { createCipheriv, createHash, randomUUID } from "node:crypto";
import { load } from "cheerio";
//#region lib/routes/baidu/baijiahao.ts
const abdrKey = "F617E80F5BD64F5A";
const abdrIv = "636014d173e04409";
const abdrKeyId = "a148fdf866c24529";
const fingerprint = {
1: "1",
4: "30",
5: "1512x982",
6: "1512x944",
7: ",",
8: [
"PDF Viewer",
"Chrome PDF Viewer",
"Chromium PDF Viewer",
"Microsoft Edge PDF Viewer",
"WebKit built-in PDF"
].map((name) => encodeURIComponent(name)).join(","),
9: ["Portable Document Format", "Portable Document Format"].map((description) => encodeURIComponent(description)).join(","),
11: "1",
12: "1",
13: "true",
14: "0",
15: "en-US",
16: "",
17: "1,0,1,1,1,1",
18: "2",
19: "8",
20: "0",
21: "",
22: "Gecko,20030107,Google Inc.,,Mozilla,Netscape,MacIntel",
23: "0,0,0",
24: "1",
28: "false,false",
29: "true,true,true",
30: 0,
31: 8,
32: "31",
34: "MacIntel",
35: "false,true",
41: true,
42: 0,
43: null,
44: 1,
60: false,
61: false,
62: false,
63: true,
64: false,
65: true,
69: 0,
70: 0,
71: "",
72: "en-US,en",
79: "0,0,0,0,0",
80: "0,0,0,0,0",
81: "0",
106: 2041,
107: "2.9.17",
112: "",
113: "",
114: "",
115: "",
198: 33,
199: "",
200: "1"
};
const sha1 = () => createHash("sha1").update(randomUUID()).digest("hex");
const route = {
path: "/baijiahao/:id/:tab?",
categories: ["new-media"],
example: "/baidu/baijiahao/3617",
parameters: {
id: "Account id, the `app_id` in the URL of the author page",
tab: {
description: "Content type",
options: [
{
value: "main",
label: "全部"
},
{
value: "article",
label: "文章"
},
{
value: "dynamic",
label: "动态"
}
],
default: "main"
}
},
name: "百家号",
maintainers: ["TonyRL"],
handler,
url: "baijiahao.baidu.com"
};
async function handler(ctx) {
const { id, tab = "main" } = ctx.req.param();
const limit = ctx.req.query("limit") ?? 20;
const link = `https://baijiahao.baidu.com/u?app_id=${id}`;
const page = await rofetch(link, { headerGeneratorOptions: PRESETS.MODERN_IOS });
const { user } = JSON.parse(page.match(/window\.runtime= (\{.*?\}),window\.runtime\.pageType/)[1]);
const abSr = await cache_default.tryGet("baidu:baijiahao:ab_sr", async () => {
const { "user-agent": ua } = generateHeaders(PRESETS.MODERN_MACOS_CHROME);
const cipher = createCipheriv("aes-128-cbc", abdrKey, abdrIv);
const plaintext = JSON.stringify({
...fingerprint,
3: sha1(),
25: `Google Inc. (Apple),ANGLE (Apple, ANGLE Metal Renderer: Apple M${Math.ceil(Math.random() * 6)}, Unspecified Version)`,
27: ua,
78: `${sha1()}_${sha1()}`,
82: sha1(),
85: sha1(),
101: sha1(),
103: String(Date.now()),
108: link,
109: ""
});
const data = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]).toString("hex");
return (await rofetch.raw("https://miao.baidu.com/abdr", {
method: "POST",
body: Buffer.from(JSON.stringify({
data,
key_id: abdrKeyId
})).toString("base64"),
headers: {
"content-type": "text/plain;charset=UTF-8",
origin: "https://baijiahao.baidu.com",
"user-agent": ua
}
})).headers.get("ab-sr");
}, config.cache.routeExpire, false);
const { data } = await rofetch("https://mbd.baidu.com/webpage", {
query: {
tab,
num: limit,
uk: user.uk,
source: "pc",
type: "newhome",
action: "dynamic",
format: "json"
},
headers: {
cookie: `ab_sr=${abSr}`,
referer: "https://baijiahao.baidu.com/"
}
});
const list = data.list.filter((item) => item.itemData.url).map((item) => {
const { title, url, imgSrc, vertical_cover: cover, rmb_videoInfoExt: videoInfo } = item.itemData;
const images = [imgSrc ?? cover ?? []].flat().map((image) => typeof image === "string" ? image : image.src);
const video = videoInfo ? JSON.parse(videoInfo) : void 0;
const quality = video && [
"1080p",
"sc",
"hd",
"default",
"360p"
].find((name) => video[name]);
const source = quality && (video[quality][`${quality}UrlHttps`] ?? video[quality][`${quality}UrlHttp`])?.replace("http://", "https://");
return {
title,
link: url,
author: user.nickname,
pubDate: parseDate(item.dynamic_ctime, "X"),
description: [source ? `<video src="${source}" poster="${images[0]}" controls preload="metadata"></video>` : images.map((image) => `<img src="${image}">`).join(""), title.replaceAll("\n", "<br>")].join("")
};
});
const items = await Promise.all(list.map((item) => item.link.startsWith("https://baijiahao.baidu.com/s?") ? cache_default.tryGet(item.link, async () => {
item.description = load(await rofetch(item.link))("[data-testid=article]").html();
return item;
}) : item));
return {
title: `${user.nickname} - 百家号`,
description: user.sign,
link,
image: user.avatar,
item: items
};
}
//#endregion
export { route };