🐞 fix: 修复 xhs 无法解析 && 微创重构 xhs 结构

This commit is contained in:
zhiyu1998 2024-10-30 23:58:10 +08:00
parent 58ceb8f5dd
commit 032a3e177b

View File

@ -85,7 +85,7 @@ import {
downloadImg, downloadImg,
estimateReadingTime, estimateReadingTime,
formatBiliInfo, formatBiliInfo,
retryAxiosReq, retryAxiosReq, saveJsonToFile,
secondsToTime, secondsToTime,
testProxy, testProxy,
truncateString, truncateString,
@ -1339,36 +1339,52 @@ export class tools extends plugin {
// 注入ck // 注入ck
XHS_NO_WATERMARK_HEADER.cookie = this.xiaohongshuCookie; XHS_NO_WATERMARK_HEADER.cookie = this.xiaohongshuCookie;
// 解析短号 // 解析短号
let id; let id, xsecToken, xsecSource;
if (msgUrl.includes("xhslink")) { if (msgUrl.includes("xhslink")) {
await fetch(msgUrl, { await fetch(msgUrl, {
headers: XHS_NO_WATERMARK_HEADER, headers: XHS_NO_WATERMARK_HEADER,
redirect: "follow", redirect: "follow",
}).then(resp => { }).then(resp => {
const uri = decodeURIComponent(resp.url); const uri = decodeURIComponent(resp.url);
const parsedUrl = new URL(resp.url);
// 如果出现了网页验证uri:https://www.xiaohongshu.com/website-login/captcha?redirectPath=https://www.xiaohongshu.com/discovery/item/63c93ac3000000002203b28a?app_platform=android&app_version=8.23.1&author_share=1&ignoreEngage=true&share_from_user_hidden=true&type=normal&xhsshare=CopyLink&appuid=62c58b90000000000303dc54&apptime=1706149572&exSource=&verifyUuid=a5f32b62-453e-426b-98fe-2cfe0c16776d&verifyType=102&verifyBiz=461 // 如果出现了网页验证uri:https://www.xiaohongshu.com/website-login/captcha?redirectPath=https://www.xiaohongshu.com/discovery/item/63c93ac3000000002203b28a?app_platform=android&app_version=8.23.1&author_share=1&ignoreEngage=true&share_from_user_hidden=true&type=normal&xhsshare=CopyLink&appuid=62c58b90000000000303dc54&apptime=1706149572&exSource=&verifyUuid=a5f32b62-453e-426b-98fe-2cfe0c16776d&verifyType=102&verifyBiz=461
const verify = uri.match(/\/item\/([0-9a-fA-F]+)/); const verify = uri.match(/\/item\/([0-9a-fA-F]+)/);
// 一般情况下不会出现问题就使用这个正则 // 一般情况下不会出现问题就使用这个正则
id = /noteId=(\w+)/.exec(uri)?.[1] ?? verify?.[1]; id = /noteId=(\w+)/.exec(uri)?.[1] ?? verify?.[1];
// 提取 xsec_source 和 xsec_token 参数
xsecSource = parsedUrl.searchParams.get("xsec_source") ?? "pc_feed";
xsecToken = parsedUrl.searchParams.get("xsec_token");
}); });
} else { } else {
const parsedUrl = new URL(msgUrl);
id = /explore\/(\w+)/.exec(msgUrl)?.[1] || /discovery\/item\/(\w+)/.exec(msgUrl)?.[1]; id = /explore\/(\w+)/.exec(msgUrl)?.[1] || /discovery\/item\/(\w+)/.exec(msgUrl)?.[1];
// 提取 xsec_source 和 xsec_token 参数
xsecSource = parsedUrl.searchParams.get("xsec_source") ?? "pc_feed";
xsecToken = parsedUrl.searchParams.get("xsec_token");
} }
const downloadPath = `${ this.getCurDownloadPath(e) }`; const downloadPath = `${ this.getCurDownloadPath(e) }`;
// 检测没有 cookie 则退出 // 检测没有 cookie 则退出
if (_.isEmpty(this.xiaohongshuCookie)) { if (_.isEmpty(this.xiaohongshuCookie) || _.isEmpty(id) || _.isEmpty(xsecToken) || _.isEmpty(xsecSource)) {
e.reply(`2024-8-2后反馈必须使用ck不然无法解析请填写相关ck\n${ HELP_DOC }`); e.reply(`请检查以下问题:\n1. 是否填写 Cookie\n2. 链接是否有id\n3. 是否填写 xsec_token 和 xsec_source\n${ HELP_DOC }`);
return; return;
} }
// 获取信息 // 获取信息
fetch(`${ XHS_REQ_LINK }${ id }`, { const resp = await fetch(`${ XHS_REQ_LINK }${ id }?xsec_token=${xsecToken}&xsec_source=${xsecSource}`, {
headers: XHS_NO_WATERMARK_HEADER, headers: XHS_NO_WATERMARK_HEADER,
}).then(async resp => { });
// 从网页获取数据
const xhsHtml = await resp.text(); const xhsHtml = await resp.text();
const reg = /window\.__INITIAL_STATE__=(.*?)<\/script>/; const reg = /window\.__INITIAL_STATE__=(.*?)<\/script>/;
const res = xhsHtml.match(reg)[1].replace(/undefined/g, "null"); const res = xhsHtml.match(reg)[1].replace(/undefined/g, "null");
const resJson = JSON.parse(res); const resJson = JSON.parse(res);
const noteData = resJson.note.noteDetailMap[id].note; saveJsonToFile(resJson);
// 检测无效 Cookie
if (resJson?.note === undefined || resJson?.note?.noteDetailMap?.[id]?.note === undefined) {
e.reply(`检测到无效的小红书 Cookie可以尝试清除缓存和cookie 或者 换一个浏览器进行获取\n${ HELP_DOC }`);
return;
}
// 提取出数据
const noteData = resJson?.note?.noteDetailMap?.[id]?.note;
const { title, desc, type } = noteData; const { title, desc, type } = noteData;
if (type === "video") { if (type === "video") {
// 封面 // 封面
@ -1418,7 +1434,6 @@ export class tools extends plugin {
// 批量删除下载的文件 // 批量删除下载的文件
await Promise.all(paths.map(item => fs.promises.rm(item, { force: true }))); await Promise.all(paths.map(item => fs.promises.rm(item, { force: true })));
} }
});
return true; return true;
} }