@ikenxuan/amagi 6.1.3 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/default/index.cjs +355 -157
- package/dist/default/index.d.ts +810 -300
- package/dist/default/index.mjs +350 -152
- package/dist/exports/axios.cjs +2 -2
- package/dist/exports/express.cjs +2 -2
- package/package.json +21 -21
- /package/dist/{chunk-CKQMccvm.cjs → rolldown-runtime-D6vf50IK.cjs} +0 -0
package/dist/default/index.cjs
CHANGED
|
@@ -2,22 +2,22 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const
|
|
5
|
+
const require_rolldown_runtime = require("../rolldown-runtime-D6vf50IK.cjs");
|
|
6
6
|
let node_url = require("node:url");
|
|
7
|
-
node_url =
|
|
7
|
+
node_url = require_rolldown_runtime.__toESM(node_url, 1);
|
|
8
8
|
let node_events = require("node:events");
|
|
9
9
|
let zod = require("zod");
|
|
10
|
-
zod =
|
|
10
|
+
zod = require_rolldown_runtime.__toESM(zod, 1);
|
|
11
11
|
let _ikenxuan_xhshow_ts = require("@ikenxuan/xhshow-ts");
|
|
12
12
|
let node_crypto = require("node:crypto");
|
|
13
|
-
node_crypto =
|
|
13
|
+
node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
|
|
14
14
|
let axios = require("axios");
|
|
15
|
-
axios =
|
|
15
|
+
axios = require_rolldown_runtime.__toESM(axios, 1);
|
|
16
16
|
let chalk = require("chalk");
|
|
17
17
|
let protobufjs = require("protobufjs");
|
|
18
|
-
protobufjs =
|
|
18
|
+
protobufjs = require_rolldown_runtime.__toESM(protobufjs, 1);
|
|
19
19
|
let express = require("express");
|
|
20
|
-
express =
|
|
20
|
+
express = require_rolldown_runtime.__toESM(express, 1);
|
|
21
21
|
//#region src/utils/deprecation.ts
|
|
22
22
|
/**
|
|
23
23
|
* 废弃 API 注册表
|
|
@@ -1349,12 +1349,194 @@ const KuaishouMethodRoutes = {
|
|
|
1349
1349
|
emojiList: "/fetch_emoji_list"
|
|
1350
1350
|
};
|
|
1351
1351
|
//#endregion
|
|
1352
|
+
//#region src/platform/xiaohongshu/sign/config.ts
|
|
1353
|
+
/** 初始化签名配置。 */
|
|
1354
|
+
const createXiaohongshuCryptoConfig = () => new _ikenxuan_xhshow_ts.CryptoConfig().withOverrides({
|
|
1355
|
+
DATA_WEB_BUILD: "6.12.3",
|
|
1356
|
+
SIGNATURE_DATA_TEMPLATE: {
|
|
1357
|
+
x0: "4.3.5",
|
|
1358
|
+
x1: "xhs-pc-web",
|
|
1359
|
+
x2: "Windows",
|
|
1360
|
+
x3: "",
|
|
1361
|
+
x4: ""
|
|
1362
|
+
},
|
|
1363
|
+
SIGNATURE_XSCOMMON_TEMPLATE: {
|
|
1364
|
+
s0: 5,
|
|
1365
|
+
s1: "",
|
|
1366
|
+
x0: "1",
|
|
1367
|
+
x1: "4.3.5",
|
|
1368
|
+
x2: "Windows",
|
|
1369
|
+
x3: "xhs-pc-web",
|
|
1370
|
+
x4: "6.12.3",
|
|
1371
|
+
x5: "",
|
|
1372
|
+
x6: "",
|
|
1373
|
+
x7: "",
|
|
1374
|
+
x8: "",
|
|
1375
|
+
x9: -596800761,
|
|
1376
|
+
x10: 0,
|
|
1377
|
+
x11: "normal"
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1380
|
+
//#endregion
|
|
1381
|
+
//#region src/platform/xiaohongshu/sign/guestCookie.ts
|
|
1382
|
+
/** @see https://github.com/Cialle/RedCrack */
|
|
1383
|
+
/** 小红书 Web 端游客会话初始化使用的浏览器请求头。 */
|
|
1384
|
+
const GUEST_HEADERS = {
|
|
1385
|
+
accept: "application/json, text/plain, */*",
|
|
1386
|
+
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
|
|
1387
|
+
"content-type": "application/json;charset=UTF-8",
|
|
1388
|
+
origin: "https://www.xiaohongshu.com",
|
|
1389
|
+
priority: "u=1, i",
|
|
1390
|
+
referer: "https://www.xiaohongshu.com/",
|
|
1391
|
+
"sec-ch-ua": "\"Microsoft Edge\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"",
|
|
1392
|
+
"sec-ch-ua-mobile": "?0",
|
|
1393
|
+
"sec-ch-ua-platform": "\"Windows\"",
|
|
1394
|
+
"sec-fetch-dest": "empty",
|
|
1395
|
+
"sec-fetch-mode": "cors",
|
|
1396
|
+
"sec-fetch-site": "same-site",
|
|
1397
|
+
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0"
|
|
1398
|
+
};
|
|
1399
|
+
/** 生成 a1 随机段时使用的 Web 端字符集。 */
|
|
1400
|
+
const COOKIE_RANDOM_CHARS = "abcdefghijklmnopqrstuvwxyz1234567890";
|
|
1401
|
+
/** 将 Cookie Jar 序列化为可直接写入 HTTP Cookie 请求头的字符串。 */
|
|
1402
|
+
const toCookieString = (cookies) => Object.entries(cookies).map(([key, value]) => `${key}=${value}`).join("; ");
|
|
1403
|
+
/** 将响应头中的 Set-Cookie 字段合并到当前游客会话的 Cookie Jar。 */
|
|
1404
|
+
const updateCookiesFromResponse = (cookies, setCookie) => {
|
|
1405
|
+
const headers = Array.isArray(setCookie) ? setCookie : setCookie ? [setCookie] : [];
|
|
1406
|
+
for (const header of headers) {
|
|
1407
|
+
const [nameValue] = header.split(";", 1);
|
|
1408
|
+
const separatorIndex = nameValue.indexOf("=");
|
|
1409
|
+
if (separatorIndex > 0) cookies[nameValue.slice(0, separatorIndex).trim()] = nameValue.slice(separatorIndex + 1).trim();
|
|
1410
|
+
}
|
|
1411
|
+
};
|
|
1412
|
+
/** 按小红书 Web 端规则生成 a1,以及由 a1 派生的 webId。 */
|
|
1413
|
+
const generateA1AndWebId = () => {
|
|
1414
|
+
const source = `${Date.now().toString(16)}${Array.from((0, node_crypto.randomBytes)(30), (byte) => COOKIE_RANDOM_CHARS[byte % 36]).join("")}5000`;
|
|
1415
|
+
const a1 = `${source}${crc32(source)}`.slice(0, 52);
|
|
1416
|
+
return {
|
|
1417
|
+
a1,
|
|
1418
|
+
webId: (0, node_crypto.createHash)("md5").update(a1).digest("hex")
|
|
1419
|
+
};
|
|
1420
|
+
};
|
|
1421
|
+
/** 计算与浏览器端实现兼容的无符号 CRC32 校验值。 */
|
|
1422
|
+
const crc32 = (input) => {
|
|
1423
|
+
let value = 4294967295;
|
|
1424
|
+
for (const byte of Buffer.from(input)) {
|
|
1425
|
+
value ^= byte;
|
|
1426
|
+
for (let bit = 0; bit < 8; bit += 1) value = value & 1 ? value >>> 1 ^ 3988292384 : value >>> 1;
|
|
1427
|
+
}
|
|
1428
|
+
return (value ^ 4294967295) >>> 0;
|
|
1429
|
+
};
|
|
1430
|
+
/** 从 scripting 接口返回的 VMP 数据中解码 websectiga Cookie。 */
|
|
1431
|
+
const generateWebsectiga = (payload) => {
|
|
1432
|
+
const bMatch = payload.match(/"b":"(.*?)",/);
|
|
1433
|
+
const dMatch = payload.match(/"d":(.*?)\}\)/);
|
|
1434
|
+
if (!bMatch || !dMatch) throw new Error("小红书 scripting 响应格式异常,无法生成 websectiga");
|
|
1435
|
+
const decoderData = JSON.parse(dMatch[1]);
|
|
1436
|
+
const encoded = Buffer.from(bMatch[1], "base64").toString("utf8");
|
|
1437
|
+
const logicList = [];
|
|
1438
|
+
for (let index = 0; index < encoded.length; index += 5) logicList.push(Array.from(encoded.slice(index, index + 5), (char) => char.charCodeAt(0) - 1));
|
|
1439
|
+
const start = decoderData[92];
|
|
1440
|
+
const end = decoderData[93];
|
|
1441
|
+
const target = logicList.slice(start, end + 1);
|
|
1442
|
+
const key = Array.from({ length: 64 }, (_, index) => {
|
|
1443
|
+
const item = target[675 + index * 2];
|
|
1444
|
+
if (!item) throw new Error("小红书 scripting 响应缺少 websectiga 解码数据");
|
|
1445
|
+
return decoderData[item[2]];
|
|
1446
|
+
});
|
|
1447
|
+
return Array.from({ length: 8 }, (_, group) => {
|
|
1448
|
+
const offset = 56 - group * 8;
|
|
1449
|
+
return String.fromCharCode(...key.slice(offset, offset + 8));
|
|
1450
|
+
}).join("");
|
|
1451
|
+
};
|
|
1452
|
+
/** 将浏览器指纹编码为 webprofile 接口要求的 DES-ECB profileData。 */
|
|
1453
|
+
const encryptProfileData = (fingerprint, desKey) => {
|
|
1454
|
+
const encoded = Buffer.from(JSON.stringify(fingerprint)).toString("base64");
|
|
1455
|
+
const blockSize = 8;
|
|
1456
|
+
const padding = blockSize - encoded.length % blockSize;
|
|
1457
|
+
const plaintext = Buffer.concat([Buffer.from(encoded), Buffer.alloc(padding)]);
|
|
1458
|
+
const cipher = (0, node_crypto.createCipheriv)("des-ede3", Buffer.from(desKey.repeat(3)), null);
|
|
1459
|
+
cipher.setAutoPadding(false);
|
|
1460
|
+
return Buffer.concat([cipher.update(plaintext), cipher.final()]).toString("hex");
|
|
1461
|
+
};
|
|
1462
|
+
/** 将 scripting 的 JSON 或 JSONP 响应统一还原为结构化数据。 */
|
|
1463
|
+
const unwrapScriptingResponse = (data) => {
|
|
1464
|
+
if (typeof data === "string") {
|
|
1465
|
+
const json = data.match(/^[^(]+\((.*)\)$/s)?.[1];
|
|
1466
|
+
return JSON.parse(json ?? data);
|
|
1467
|
+
}
|
|
1468
|
+
return data;
|
|
1469
|
+
};
|
|
1470
|
+
/**
|
|
1471
|
+
* 创建小红书 Web 端游客会话 Cookie。
|
|
1472
|
+
*
|
|
1473
|
+
* 该流程对应 Web 端首次访问时的 Cookie 初始化:生成 a1/webId,完成
|
|
1474
|
+
* scripting、webprofile 与 activate 三个会话请求,并返回最终 Cookie 字符串。
|
|
1475
|
+
*/
|
|
1476
|
+
const createXiaohongshuGuestCookie = async (requestConfig) => {
|
|
1477
|
+
const cryptoConfig = createXiaohongshuCryptoConfig();
|
|
1478
|
+
const signer = new _ikenxuan_xhshow_ts.Xhshow(cryptoConfig);
|
|
1479
|
+
const cookies = {
|
|
1480
|
+
...generateA1AndWebId(),
|
|
1481
|
+
webBuild: cryptoConfig.DATA_WEB_BUILD,
|
|
1482
|
+
xsecappid: "xhs-pc-web",
|
|
1483
|
+
loadts: String(Date.now()),
|
|
1484
|
+
abRequestId: (0, node_crypto.randomUUID)()
|
|
1485
|
+
};
|
|
1486
|
+
const { headers: requestHeaders, params: _params, ...transportConfig } = requestConfig ?? {};
|
|
1487
|
+
/** 发送会话初始化请求,并将响应中的 Set-Cookie 合并回当前 Cookie Jar。 */
|
|
1488
|
+
const request = async (url, data, signed = false) => {
|
|
1489
|
+
const signatureHeaders = signed ? signer.signHeadersPost(new URL(url).pathname, cookies, "xhs-pc-web", data) : {};
|
|
1490
|
+
const response = await (0, axios.default)({
|
|
1491
|
+
...transportConfig,
|
|
1492
|
+
method: "POST",
|
|
1493
|
+
url,
|
|
1494
|
+
data,
|
|
1495
|
+
validateStatus: () => true,
|
|
1496
|
+
headers: {
|
|
1497
|
+
...GUEST_HEADERS,
|
|
1498
|
+
...requestHeaders,
|
|
1499
|
+
...signatureHeaders,
|
|
1500
|
+
Cookie: toCookieString(cookies)
|
|
1501
|
+
}
|
|
1502
|
+
});
|
|
1503
|
+
updateCookiesFromResponse(cookies, response.headers["set-cookie"]);
|
|
1504
|
+
if (response.status < 200 || response.status >= 300) throw new Error(`小红书游客会话初始化失败:${url} 返回 HTTP ${response.status}`);
|
|
1505
|
+
return response.data;
|
|
1506
|
+
};
|
|
1507
|
+
const scriptingData = unwrapScriptingResponse(await request("https://as.xiaohongshu.com/api/sec/v1/scripting", {
|
|
1508
|
+
callFrom: "web",
|
|
1509
|
+
callback: "seccallback"
|
|
1510
|
+
})).data;
|
|
1511
|
+
if (!scriptingData?.data || !scriptingData.secPoisonId) throw new Error("小红书 scripting 响应缺少游客会话数据");
|
|
1512
|
+
cookies.websectiga = generateWebsectiga(scriptingData.data);
|
|
1513
|
+
cookies.sec_poison_id = scriptingData.secPoisonId;
|
|
1514
|
+
const fingerprint = new _ikenxuan_xhshow_ts.FingerprintGenerator(cryptoConfig).generate(cookies, GUEST_HEADERS["user-agent"]);
|
|
1515
|
+
await request(cryptoConfig.GID_URL, {
|
|
1516
|
+
platform: cryptoConfig.DATA_PLATFORM,
|
|
1517
|
+
profileData: encryptProfileData(fingerprint, cryptoConfig.DES_KEY),
|
|
1518
|
+
sdkVersion: cryptoConfig.DATA_SDK_VERSION,
|
|
1519
|
+
svn: cryptoConfig.DATA_SVN
|
|
1520
|
+
}, true);
|
|
1521
|
+
await request("https://edith.xiaohongshu.com/api/sns/web/v1/login/activate", {}, true);
|
|
1522
|
+
if (!cookies.web_session) throw new Error("小红书游客会话初始化失败:未获取到 web_session");
|
|
1523
|
+
return toCookieString(cookies);
|
|
1524
|
+
};
|
|
1525
|
+
//#endregion
|
|
1352
1526
|
//#region src/platform/xiaohongshu/sign/index.ts
|
|
1353
1527
|
/**
|
|
1354
1528
|
* 小红书签名算法类
|
|
1355
1529
|
*/
|
|
1356
1530
|
var xiaohongshuSign = class {
|
|
1357
|
-
static client = new _ikenxuan_xhshow_ts.Xhshow();
|
|
1531
|
+
static client = new _ikenxuan_xhshow_ts.Xhshow(createXiaohongshuCryptoConfig());
|
|
1532
|
+
/**
|
|
1533
|
+
* 创建包含 web_session 的小红书 Web 端游客 Cookie。
|
|
1534
|
+
*
|
|
1535
|
+
* `requestConfig` 会透传到游客会话初始化请求,可用于配置代理、超时等传输参数。
|
|
1536
|
+
*/
|
|
1537
|
+
static createGuestCookie(requestConfig) {
|
|
1538
|
+
return createXiaohongshuGuestCookie(requestConfig);
|
|
1539
|
+
}
|
|
1358
1540
|
/**
|
|
1359
1541
|
* 生成GET请求的X-S签名
|
|
1360
1542
|
* @param path - API路径
|
|
@@ -1567,7 +1749,7 @@ const xiaohongshuApiUrls = {
|
|
|
1567
1749
|
* @param data - 请求参数
|
|
1568
1750
|
* @returns 完整的接口URL
|
|
1569
1751
|
*/
|
|
1570
|
-
emojiList(
|
|
1752
|
+
emojiList(_data) {
|
|
1571
1753
|
return {
|
|
1572
1754
|
apiPath: "/api/im/redmoji/detail",
|
|
1573
1755
|
Url: "https://edith.xiaohongshu.com/api/im/redmoji/detail"
|
|
@@ -2473,7 +2655,7 @@ const generateSecChUa = (userAgent) => {
|
|
|
2473
2655
|
*/
|
|
2474
2656
|
const getDouyinDefaultConfig = (cookie, requestConfig) => {
|
|
2475
2657
|
let finalUserAgent = requestConfig?.headers?.["User-Agent"] ?? "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36";
|
|
2476
|
-
finalUserAgent = finalUserAgent.replace(/\s+Edg\/[\d
|
|
2658
|
+
finalUserAgent = finalUserAgent.replace(/\s+Edg\/[\d.]+/g, "");
|
|
2477
2659
|
const defHeaders = {
|
|
2478
2660
|
Accept: "application/json, text/plain, */*",
|
|
2479
2661
|
"Accept-Encoding": "gzip, deflate, br, zstd",
|
|
@@ -2648,7 +2830,8 @@ var SM3 = class {
|
|
|
2648
2830
|
this.chunk = this.chunk.concat(a.slice(0, f));
|
|
2649
2831
|
while (this.chunk.length >= 64) {
|
|
2650
2832
|
this._compress(this.chunk);
|
|
2651
|
-
f < a.length
|
|
2833
|
+
if (f < a.length) this.chunk = a.slice(f, Math.min(f + 64, a.length));
|
|
2834
|
+
else this.chunk = [];
|
|
2652
2835
|
f += 64;
|
|
2653
2836
|
}
|
|
2654
2837
|
}
|
|
@@ -2684,10 +2867,17 @@ var SM3 = class {
|
|
|
2684
2867
|
if (t.length < 64) console.error("compress error: not enough data");
|
|
2685
2868
|
else {
|
|
2686
2869
|
for (var f = ((e) => {
|
|
2687
|
-
for (var r = new Array(132), t = 0; t < 16; t++)
|
|
2870
|
+
for (var r = new Array(132), t = 0; t < 16; t++) {
|
|
2871
|
+
r[t] = e[4 * t] << 24;
|
|
2872
|
+
r[t] |= e[4 * t + 1] << 16;
|
|
2873
|
+
r[t] |= e[4 * t + 2] << 8;
|
|
2874
|
+
r[t] |= e[4 * t + 3];
|
|
2875
|
+
r[t] >>>= 0;
|
|
2876
|
+
}
|
|
2688
2877
|
for (var n = 16; n < 68; n++) {
|
|
2689
2878
|
let a = r[n - 16] ^ r[n - 9] ^ this.le(r[n - 3], 15);
|
|
2690
|
-
a = a ^ this.le(a, 15) ^ this.le(a, 23)
|
|
2879
|
+
a = a ^ this.le(a, 15) ^ this.le(a, 23);
|
|
2880
|
+
r[n] = (a ^ this.le(r[n - 13], 7) ^ r[n - 6]) >>> 0;
|
|
2691
2881
|
}
|
|
2692
2882
|
for (n = 0; n < 64; n++) r[n + 68] = (r[n] ^ r[n + 4]) >>> 0;
|
|
2693
2883
|
return r;
|
|
@@ -2697,7 +2887,15 @@ var SM3 = class {
|
|
|
2697
2887
|
let u = this.pe(c, i[0], i[1], i[2]);
|
|
2698
2888
|
u = (4294967295 & (u = u + i[3] + s + f[c + 68])) >>> 0;
|
|
2699
2889
|
let b = this.he(c, i[4], i[5], i[6]);
|
|
2700
|
-
b = (4294967295 & (b = b + i[7] + o + f[c])) >>> 0
|
|
2890
|
+
b = (4294967295 & (b = b + i[7] + o + f[c])) >>> 0;
|
|
2891
|
+
i[3] = i[2];
|
|
2892
|
+
i[2] = this.le(i[1], 9);
|
|
2893
|
+
i[1] = i[0];
|
|
2894
|
+
i[0] = u;
|
|
2895
|
+
i[7] = i[6];
|
|
2896
|
+
i[6] = this.le(i[5], 19);
|
|
2897
|
+
i[5] = i[4];
|
|
2898
|
+
i[4] = (b ^ this.le(b, 9) ^ this.le(b, 17)) >>> 0;
|
|
2701
2899
|
}
|
|
2702
2900
|
for (let l = 0; l < 8; l++) this.reg[l] = (this.reg[l] ^ i[l]) >>> 0;
|
|
2703
2901
|
}
|
|
@@ -3008,7 +3206,7 @@ function generate_random_str() {
|
|
|
3008
3206
|
* @returns 清理后的User-Agent字符串
|
|
3009
3207
|
*/
|
|
3010
3208
|
const cleanUserAgentForSigning = (userAgent) => {
|
|
3011
|
-
return userAgent.replace(/\s+Edg\/[\d
|
|
3209
|
+
return userAgent.replace(/\s+Edg\/[\d.]+/g, "");
|
|
3012
3210
|
};
|
|
3013
3211
|
/**
|
|
3014
3212
|
* 抖音a_bogus签名算法
|
|
@@ -3130,7 +3328,6 @@ var XBogus = class {
|
|
|
3130
3328
|
const array2 = this.md5StrToArray(this.md5(this.md5StrToArray("d41d8cd98f00b204e9800998ecf8427e")));
|
|
3131
3329
|
const urlEncryptedArray = this.md5Encrypt(urlPath);
|
|
3132
3330
|
const timestamp = Math.floor(Date.now() / 1e3);
|
|
3133
|
-
const ct = 536919696;
|
|
3134
3331
|
const newArray = [
|
|
3135
3332
|
64,
|
|
3136
3333
|
1,
|
|
@@ -3146,10 +3343,10 @@ var XBogus = class {
|
|
|
3146
3343
|
timestamp >> 16 & 255,
|
|
3147
3344
|
timestamp >> 8 & 255,
|
|
3148
3345
|
timestamp & 255,
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3346
|
+
32,
|
|
3347
|
+
0,
|
|
3348
|
+
190,
|
|
3349
|
+
144
|
|
3153
3350
|
];
|
|
3154
3351
|
let xorResult = newArray[0];
|
|
3155
3352
|
for (let i = 1; i < newArray.length; i++) xorResult ^= newArray[i];
|
|
@@ -4069,7 +4266,7 @@ const DouyinData = async (data, cookie, requestConfig) => {
|
|
|
4069
4266
|
if (isInvalidResponse) {
|
|
4070
4267
|
const desc = `抖音${typeStr}搜索返回无有效数据,疑似触发反爬机制,你的抖音Cookie可能已经失效!`;
|
|
4071
4268
|
const warningMessage = `
|
|
4072
|
-
获取响应数据失败!原因:${
|
|
4269
|
+
获取响应数据失败!原因:${typeStr}搜索返回无有效数据,疑似触发反爬机制
|
|
4073
4270
|
请求类型:「${data.methodType}」
|
|
4074
4271
|
搜索关键词:「${data.query}」
|
|
4075
4272
|
请求URL:${url}
|
|
@@ -4088,12 +4285,12 @@ const DouyinData = async (data, cookie, requestConfig) => {
|
|
|
4088
4285
|
if (!list || list.length === 0) {
|
|
4089
4286
|
const desc = `抖音${typeStr}搜索接口第一次请求就返回空数组,可能该关键词无搜索结果或触发风控限制,你的抖音Cookie可能已经失效!`;
|
|
4090
4287
|
const warningMessage = `
|
|
4091
|
-
获取响应数据失败!原因:${
|
|
4288
|
+
获取响应数据失败!原因:${typeStr}搜索接口第一次请求就返回空数组,你的抖音Cookie可能已经失效!
|
|
4092
4289
|
请求类型:「${data.methodType}」
|
|
4093
4290
|
搜索关键词:「${data.query}」
|
|
4094
4291
|
请求URL:${url}
|
|
4095
4292
|
`;
|
|
4096
|
-
|
|
4293
|
+
emitLogWarn(warningMessage);
|
|
4097
4294
|
return {
|
|
4098
4295
|
data: raw,
|
|
4099
4296
|
amagiError: {
|
|
@@ -4184,7 +4381,7 @@ const DouyinData = async (data, cookie, requestConfig) => {
|
|
|
4184
4381
|
});
|
|
4185
4382
|
currentStart = currentEnd;
|
|
4186
4383
|
}
|
|
4187
|
-
|
|
4384
|
+
emitLogDebug(`弹幕数据需要分${segments.length}段获取,总时长:${totalDuration}ms`);
|
|
4188
4385
|
const segmentPromises = segments.map(async (segment, index) => {
|
|
4189
4386
|
const url = douyinApiUrls.getDanmakuList({
|
|
4190
4387
|
aweme_id: data.aweme_id,
|
|
@@ -4197,10 +4394,10 @@ const DouyinData = async (data, cookie, requestConfig) => {
|
|
|
4197
4394
|
...baseRequestConfig,
|
|
4198
4395
|
url: buildSignedUrl(url, signType, userAgent)
|
|
4199
4396
|
});
|
|
4200
|
-
|
|
4397
|
+
emitLogDebug(`弹幕第${index + 1}段获取成功 (${segment.start}ms-${segment.end}ms)`);
|
|
4201
4398
|
return segmentData;
|
|
4202
4399
|
} catch (error) {
|
|
4203
|
-
|
|
4400
|
+
emitLogDebug(`弹幕第${index + 1}段获取失败 (${segment.start}ms-${segment.end}ms):`, error);
|
|
4204
4401
|
return null;
|
|
4205
4402
|
}
|
|
4206
4403
|
});
|
|
@@ -4229,7 +4426,7 @@ const DouyinData = async (data, cookie, requestConfig) => {
|
|
|
4229
4426
|
extra: finalExtra,
|
|
4230
4427
|
log_pb: finalLogPb
|
|
4231
4428
|
};
|
|
4232
|
-
|
|
4429
|
+
emitLogDebug(`弹幕数据合并完成,共获取${mergedDanmakuList.length}条弹幕`);
|
|
4233
4430
|
return finalDanmakuData;
|
|
4234
4431
|
}
|
|
4235
4432
|
default: {
|
|
@@ -4241,7 +4438,7 @@ const DouyinData = async (data, cookie, requestConfig) => {
|
|
|
4241
4438
|
url
|
|
4242
4439
|
});
|
|
4243
4440
|
}
|
|
4244
|
-
|
|
4441
|
+
emitLogWarn(`未知的抖音数据接口:「${data.methodType}」`);
|
|
4245
4442
|
return null;
|
|
4246
4443
|
}
|
|
4247
4444
|
}
|
|
@@ -4309,11 +4506,11 @@ const GlobalGetData$3 = async (type, config) => {
|
|
|
4309
4506
|
requestUrl: config.url
|
|
4310
4507
|
};
|
|
4311
4508
|
warningMessage = `
|
|
4312
|
-
|
|
4509
|
+
获取响应数据失败!原因:接口返回内容为空,你的抖音ck可能已经失效!
|
|
4313
4510
|
请求类型:「${type}」
|
|
4314
4511
|
请求URL:${config.url}
|
|
4315
4512
|
`;
|
|
4316
|
-
|
|
4513
|
+
emitLogWarn(warningMessage);
|
|
4317
4514
|
const cookieError = new Error(Err.errorDescription);
|
|
4318
4515
|
Object.assign(cookieError, {
|
|
4319
4516
|
code: "INVALID_COOKIE",
|
|
@@ -4330,11 +4527,11 @@ const GlobalGetData$3 = async (type, config) => {
|
|
|
4330
4527
|
requestUrl: config.url
|
|
4331
4528
|
};
|
|
4332
4529
|
warningMessage = `
|
|
4333
|
-
获取响应数据失败!原因:${
|
|
4530
|
+
获取响应数据失败!原因:${filterReason}
|
|
4334
4531
|
请求类型:「${type}」
|
|
4335
4532
|
请求URL:${config.url}
|
|
4336
4533
|
`;
|
|
4337
|
-
|
|
4534
|
+
emitLogWarn(warningMessage);
|
|
4338
4535
|
const filterError = new Error(Err.errorDescription);
|
|
4339
4536
|
Object.assign(filterError, {
|
|
4340
4537
|
code: "CONTENT_FILTERED",
|
|
@@ -5312,6 +5509,8 @@ const encodeBase64Url = (bytes) => {
|
|
|
5312
5509
|
* 数据流而最小化保留的局部算法。
|
|
5313
5510
|
*/
|
|
5314
5511
|
var KuaishouChaChaCipher = class {
|
|
5512
|
+
key;
|
|
5513
|
+
nonce;
|
|
5315
5514
|
wordIndex = 0;
|
|
5316
5515
|
state = new Array(16).fill(0);
|
|
5317
5516
|
constructor(key, nonce) {
|
|
@@ -6144,7 +6343,7 @@ const captureKuaishouEncodeStack = () => {
|
|
|
6144
6343
|
* @returns 用于 `SECS.s` 的栈尾字符串
|
|
6145
6344
|
*/
|
|
6146
6345
|
const deriveKuaishouSecsStackTail = (stack = captureKuaishouEncodeStack()) => {
|
|
6147
|
-
return stack.length > KUAISHOU_SECS_STACK_LIMIT ? stack.slice(-
|
|
6346
|
+
return stack.length > KUAISHOU_SECS_STACK_LIMIT ? stack.slice(-100) : stack;
|
|
6148
6347
|
};
|
|
6149
6348
|
/**
|
|
6150
6349
|
* 构造快手 `window.SECS` 的纯算法等价状态。
|
|
@@ -6997,7 +7196,7 @@ const KuaishouData = async (data, cookie, requestConfig) => {
|
|
|
6997
7196
|
}
|
|
6998
7197
|
case "emojiList": return fetchKuaishouGraphqlPayload(data.methodType, kuaishouApiUrls.emojiList());
|
|
6999
7198
|
default:
|
|
7000
|
-
|
|
7199
|
+
emitLogWarn(`Unknown Kuaishou API method: "${data.methodType}"`);
|
|
7001
7200
|
return null;
|
|
7002
7201
|
}
|
|
7003
7202
|
};
|
|
@@ -7036,12 +7235,12 @@ const GlobalGetData$2 = async (type, options, config) => {
|
|
|
7036
7235
|
requestBody: JSON.stringify(options.data)
|
|
7037
7236
|
};
|
|
7038
7237
|
warningMessage = `
|
|
7039
|
-
|
|
7238
|
+
获取响应数据失败!原因:接口返回内容为空,你的快手ck可能已经失效!
|
|
7040
7239
|
请求类型:「${type}」
|
|
7041
7240
|
请求URL:${options.url}
|
|
7042
7241
|
请求参数:${JSON.stringify(options.data, null, 2)}
|
|
7043
7242
|
`;
|
|
7044
|
-
|
|
7243
|
+
emitLogWarn(warningMessage);
|
|
7045
7244
|
const cookieError = new Error(Err.errorDescription);
|
|
7046
7245
|
Object.assign(cookieError, {
|
|
7047
7246
|
code: "INVALID_COOKIE",
|
|
@@ -7276,132 +7475,136 @@ function createBoundKuaishouFetcher(cookie, requestConfig) {
|
|
|
7276
7475
|
* @returns 返回小红书数据
|
|
7277
7476
|
*/
|
|
7278
7477
|
const XiaohongshuData = async (data, cookie, requestConfig) => {
|
|
7279
|
-
|
|
7280
|
-
const
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
...
|
|
7286
|
-
...requestConfig?.headers ?? {}
|
|
7287
|
-
}
|
|
7288
|
-
};
|
|
7289
|
-
const xiaohongshuApiUrls = createXiaohongshuApiUrls();
|
|
7290
|
-
switch (data.methodType) {
|
|
7291
|
-
case "homeFeed": return await GlobalGetData$1(data.methodType, {
|
|
7292
|
-
...baseRequestConfig,
|
|
7293
|
-
url: xiaohongshuApiUrls.homeFeed(data).Url,
|
|
7294
|
-
data: JSON.stringify(xiaohongshuApiUrls.homeFeed(data).Body),
|
|
7295
|
-
headers: {
|
|
7296
|
-
...baseRequestConfig.headers,
|
|
7297
|
-
"x-s": xiaohongshuSign.generateXSPost(xiaohongshuApiUrls.homeFeed(data).apiPath, xiaohongshuSign.extractA1FromCookie(cookie ?? ""), "xhs-pc-web", xiaohongshuApiUrls.homeFeed(data).Body),
|
|
7298
|
-
"x-s-common": xiaohongshuSign.generateXSCommon(cookie ?? ""),
|
|
7299
|
-
"x-t": xiaohongshuSign.generateXT()
|
|
7300
|
-
}
|
|
7301
|
-
});
|
|
7302
|
-
case "noteDetail": return await GlobalGetData$1(data.methodType, {
|
|
7303
|
-
...baseRequestConfig,
|
|
7304
|
-
url: xiaohongshuApiUrls.noteDetail(data).Url,
|
|
7305
|
-
data: xiaohongshuApiUrls.noteDetail(data).Body,
|
|
7478
|
+
/** 使用指定 Cookie 构建一次完整的小红书 API 请求。 */
|
|
7479
|
+
const requestWithCookie = async (requestCookie) => {
|
|
7480
|
+
const defHeaders = getXiaohongshuDefaultConfig(requestCookie)["headers"];
|
|
7481
|
+
const baseRequestConfig = {
|
|
7482
|
+
method: "POST",
|
|
7483
|
+
timeout: 1e4,
|
|
7484
|
+
...requestConfig,
|
|
7306
7485
|
headers: {
|
|
7307
|
-
...
|
|
7308
|
-
|
|
7309
|
-
"x-s-common": xiaohongshuSign.generateXSCommon(cookie ?? ""),
|
|
7310
|
-
"x-t": xiaohongshuSign.generateXT()
|
|
7486
|
+
...defHeaders,
|
|
7487
|
+
...requestConfig?.headers ?? {}
|
|
7311
7488
|
}
|
|
7312
|
-
}
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
timeout: 1e4,
|
|
7317
|
-
...requestConfig,
|
|
7318
|
-
headers: {
|
|
7319
|
-
...defHeaders,
|
|
7320
|
-
...requestConfig?.headers ?? {}
|
|
7321
|
-
}
|
|
7322
|
-
};
|
|
7323
|
-
return await GlobalGetData$1(data.methodType, {
|
|
7489
|
+
};
|
|
7490
|
+
const xiaohongshuApiUrls = createXiaohongshuApiUrls();
|
|
7491
|
+
switch (data.methodType) {
|
|
7492
|
+
case "homeFeed": return await GlobalGetData$1(data.methodType, {
|
|
7324
7493
|
...baseRequestConfig,
|
|
7325
|
-
url: xiaohongshuApiUrls.
|
|
7494
|
+
url: xiaohongshuApiUrls.homeFeed(data).Url,
|
|
7495
|
+
data: JSON.stringify(xiaohongshuApiUrls.homeFeed(data).Body),
|
|
7326
7496
|
headers: {
|
|
7327
7497
|
...baseRequestConfig.headers,
|
|
7328
|
-
"x-s": xiaohongshuSign.
|
|
7329
|
-
"x-s-common": xiaohongshuSign.generateXSCommon(
|
|
7498
|
+
"x-s": xiaohongshuSign.generateXSPost(xiaohongshuApiUrls.homeFeed(data).apiPath, xiaohongshuSign.extractA1FromCookie(requestCookie), "xhs-pc-web", xiaohongshuApiUrls.homeFeed(data).Body),
|
|
7499
|
+
"x-s-common": xiaohongshuSign.generateXSCommon(requestCookie),
|
|
7330
7500
|
"x-t": xiaohongshuSign.generateXT()
|
|
7331
7501
|
}
|
|
7332
7502
|
});
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
timeout: 1e4,
|
|
7338
|
-
...requestConfig,
|
|
7503
|
+
case "noteDetail": return await GlobalGetData$1(data.methodType, {
|
|
7504
|
+
...baseRequestConfig,
|
|
7505
|
+
url: xiaohongshuApiUrls.noteDetail(data).Url,
|
|
7506
|
+
data: xiaohongshuApiUrls.noteDetail(data).Body,
|
|
7339
7507
|
headers: {
|
|
7340
|
-
...
|
|
7341
|
-
|
|
7508
|
+
...baseRequestConfig.headers,
|
|
7509
|
+
"x-s": xiaohongshuSign.generateXSPost(xiaohongshuApiUrls.noteDetail(data).apiPath, xiaohongshuSign.extractA1FromCookie(requestCookie), "xhs-pc-web", xiaohongshuApiUrls.noteDetail(data).Body),
|
|
7510
|
+
"x-s-common": xiaohongshuSign.generateXSCommon(requestCookie),
|
|
7511
|
+
"x-t": xiaohongshuSign.generateXT()
|
|
7342
7512
|
}
|
|
7343
|
-
};
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7513
|
+
});
|
|
7514
|
+
case "noteComments": {
|
|
7515
|
+
const baseRequestConfig = {
|
|
7516
|
+
method: "GET",
|
|
7517
|
+
timeout: 1e4,
|
|
7518
|
+
...requestConfig,
|
|
7519
|
+
headers: {
|
|
7520
|
+
...defHeaders,
|
|
7521
|
+
...requestConfig?.headers ?? {}
|
|
7522
|
+
}
|
|
7523
|
+
};
|
|
7524
|
+
return await GlobalGetData$1(data.methodType, {
|
|
7347
7525
|
...baseRequestConfig,
|
|
7348
|
-
url: xiaohongshuApiUrls.
|
|
7526
|
+
url: xiaohongshuApiUrls.noteComments(data).Url,
|
|
7349
7527
|
headers: {
|
|
7350
7528
|
...baseRequestConfig.headers,
|
|
7351
|
-
"x-s": xiaohongshuSign.generateXSGet(xiaohongshuApiUrls.
|
|
7352
|
-
"x-s-common": xiaohongshuSign.generateXSCommon(
|
|
7529
|
+
"x-s": xiaohongshuSign.generateXSGet(xiaohongshuApiUrls.noteComments(data).apiPath, xiaohongshuSign.extractA1FromCookie(requestCookie), "xhs-pc-web"),
|
|
7530
|
+
"x-s-common": xiaohongshuSign.generateXSCommon(requestCookie),
|
|
7353
7531
|
"x-t": xiaohongshuSign.generateXT()
|
|
7354
7532
|
}
|
|
7355
|
-
})
|
|
7356
|
-
msg: "success"
|
|
7357
|
-
};
|
|
7358
|
-
}
|
|
7359
|
-
case "userNoteList": return await GlobalGetData$1(data.methodType, {
|
|
7360
|
-
...baseRequestConfig,
|
|
7361
|
-
method: "GET",
|
|
7362
|
-
url: xiaohongshuApiUrls.userNoteList(data).Url,
|
|
7363
|
-
headers: {
|
|
7364
|
-
...baseRequestConfig.headers,
|
|
7365
|
-
"x-b3-traceid": xiaohongshuSign.generateXB3Traceid(),
|
|
7366
|
-
"x-s": xiaohongshuSign.generateXSGet(xiaohongshuApiUrls.userNoteList(data).apiPath, xiaohongshuSign.extractA1FromCookie(cookie ?? ""), "xhs-pc-web"),
|
|
7367
|
-
"x-s-common": xiaohongshuSign.generateXSCommon(cookie ?? ""),
|
|
7368
|
-
"x-t": xiaohongshuSign.generateXT()
|
|
7533
|
+
});
|
|
7369
7534
|
}
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7535
|
+
case "userProfile": {
|
|
7536
|
+
const baseRequestConfig = {
|
|
7537
|
+
method: "GET",
|
|
7538
|
+
timeout: 1e4,
|
|
7539
|
+
...requestConfig,
|
|
7540
|
+
headers: {
|
|
7541
|
+
...defHeaders,
|
|
7542
|
+
...requestConfig?.headers ?? {}
|
|
7543
|
+
}
|
|
7544
|
+
};
|
|
7545
|
+
return {
|
|
7546
|
+
code: 0,
|
|
7547
|
+
data: extractCreatorInfoFromHtml(await GlobalGetData$1(data.methodType, {
|
|
7548
|
+
...baseRequestConfig,
|
|
7549
|
+
url: xiaohongshuApiUrls.userProfile(data).Url,
|
|
7550
|
+
headers: {
|
|
7551
|
+
...baseRequestConfig.headers,
|
|
7552
|
+
"x-s": xiaohongshuSign.generateXSGet(xiaohongshuApiUrls.userProfile(data).apiPath, xiaohongshuSign.extractA1FromCookie(requestCookie), "xhs-pc-web"),
|
|
7553
|
+
"x-s-common": xiaohongshuSign.generateXSCommon(requestCookie),
|
|
7554
|
+
"x-t": xiaohongshuSign.generateXT()
|
|
7555
|
+
}
|
|
7556
|
+
})),
|
|
7557
|
+
msg: "success"
|
|
7558
|
+
};
|
|
7559
|
+
}
|
|
7560
|
+
case "userNoteList": return await GlobalGetData$1(data.methodType, {
|
|
7561
|
+
...baseRequestConfig,
|
|
7373
7562
|
method: "GET",
|
|
7374
|
-
|
|
7375
|
-
...requestConfig,
|
|
7563
|
+
url: xiaohongshuApiUrls.userNoteList(data).Url,
|
|
7376
7564
|
headers: {
|
|
7377
|
-
...
|
|
7378
|
-
|
|
7565
|
+
...baseRequestConfig.headers,
|
|
7566
|
+
"x-b3-traceid": xiaohongshuSign.generateXB3Traceid(),
|
|
7567
|
+
"x-s": xiaohongshuSign.generateXSGet(xiaohongshuApiUrls.userNoteList(data).apiPath, xiaohongshuSign.extractA1FromCookie(requestCookie), "xhs-pc-web"),
|
|
7568
|
+
"x-s-common": xiaohongshuSign.generateXSCommon(requestCookie),
|
|
7569
|
+
"x-t": xiaohongshuSign.generateXT()
|
|
7379
7570
|
}
|
|
7380
|
-
};
|
|
7381
|
-
|
|
7571
|
+
});
|
|
7572
|
+
case "emojiList": {
|
|
7573
|
+
const baseRequestConfig = {
|
|
7574
|
+
method: "GET",
|
|
7575
|
+
timeout: 1e4,
|
|
7576
|
+
...requestConfig,
|
|
7577
|
+
headers: {
|
|
7578
|
+
...defHeaders,
|
|
7579
|
+
...requestConfig?.headers ?? {}
|
|
7580
|
+
}
|
|
7581
|
+
};
|
|
7582
|
+
return await GlobalGetData$1(data.methodType, {
|
|
7583
|
+
...baseRequestConfig,
|
|
7584
|
+
url: xiaohongshuApiUrls.emojiList(data).Url,
|
|
7585
|
+
headers: {
|
|
7586
|
+
...baseRequestConfig.headers,
|
|
7587
|
+
"x-s": xiaohongshuSign.generateXSGet(xiaohongshuApiUrls.emojiList(data).apiPath, xiaohongshuSign.extractA1FromCookie(requestCookie), "xhs-pc-web"),
|
|
7588
|
+
"x-s-common": xiaohongshuSign.generateXSCommon(requestCookie),
|
|
7589
|
+
"x-t": xiaohongshuSign.generateXT()
|
|
7590
|
+
}
|
|
7591
|
+
});
|
|
7592
|
+
}
|
|
7593
|
+
case "searchNotes": return await GlobalGetData$1(data.methodType, {
|
|
7382
7594
|
...baseRequestConfig,
|
|
7383
|
-
url: xiaohongshuApiUrls.
|
|
7595
|
+
url: xiaohongshuApiUrls.searchNotes(data).Url,
|
|
7596
|
+
data: xiaohongshuApiUrls.searchNotes(data).Body,
|
|
7384
7597
|
headers: {
|
|
7385
7598
|
...baseRequestConfig.headers,
|
|
7386
|
-
"x-s": xiaohongshuSign.
|
|
7387
|
-
"x-s-common": xiaohongshuSign.generateXSCommon(
|
|
7599
|
+
"x-s": xiaohongshuSign.generateXSPost(xiaohongshuApiUrls.searchNotes(data).apiPath, xiaohongshuSign.extractA1FromCookie(requestCookie), "xhs-pc-web"),
|
|
7600
|
+
"x-s-common": xiaohongshuSign.generateXSCommon(requestCookie),
|
|
7388
7601
|
"x-t": xiaohongshuSign.generateXT()
|
|
7389
7602
|
}
|
|
7390
7603
|
});
|
|
7604
|
+
default: throw new Error(`Unknown Xiaohongshu API method: "${data.methodType}"`);
|
|
7391
7605
|
}
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
url: xiaohongshuApiUrls.searchNotes(data).Url,
|
|
7395
|
-
data: xiaohongshuApiUrls.searchNotes(data).Body,
|
|
7396
|
-
headers: {
|
|
7397
|
-
...baseRequestConfig.headers,
|
|
7398
|
-
"x-s": xiaohongshuSign.generateXSPost(xiaohongshuApiUrls.searchNotes(data).apiPath, xiaohongshuSign.extractA1FromCookie(cookie ?? ""), "xhs-pc-web"),
|
|
7399
|
-
"x-s-common": xiaohongshuSign.generateXSCommon(cookie ?? ""),
|
|
7400
|
-
"x-t": xiaohongshuSign.generateXT()
|
|
7401
|
-
}
|
|
7402
|
-
});
|
|
7403
|
-
default: throw new Error(`Unknown Xiaohongshu API method: "${logger.red(data.methodType)}"`);
|
|
7404
|
-
}
|
|
7606
|
+
};
|
|
7607
|
+
return requestWithCookie(cookie?.trim() ?? "");
|
|
7405
7608
|
};
|
|
7406
7609
|
/**
|
|
7407
7610
|
* 全局数据获取函数
|
|
@@ -7425,7 +7628,7 @@ const GlobalGetData$1 = async (methodType, config) => {
|
|
|
7425
7628
|
if (response.code !== 0) throw new Error(`API request failed: ${response.data?.msg ?? response.msg ?? "Unknown error"}, code: ${response.code}`);
|
|
7426
7629
|
return response;
|
|
7427
7630
|
} catch (error) {
|
|
7428
|
-
|
|
7631
|
+
emitLogError(`Xiaohongshu API request failed [${methodType}]:`, error.message);
|
|
7429
7632
|
return {
|
|
7430
7633
|
code: 500,
|
|
7431
7634
|
message: "error",
|
|
@@ -7766,7 +7969,7 @@ const createNetworkErrorResult = (error, retries) => {
|
|
|
7766
7969
|
* @returns 清理后的User-Agent字符串
|
|
7767
7970
|
*/
|
|
7768
7971
|
const cleanUserAgent = (userAgent) => {
|
|
7769
|
-
return userAgent.replace(/\s+Edg\/[\d
|
|
7972
|
+
return userAgent.replace(/\s+Edg\/[\d.]+/g, "");
|
|
7770
7973
|
};
|
|
7771
7974
|
/**
|
|
7772
7975
|
* 执行网络请求并返回数据(带自动重试)
|
|
@@ -8018,8 +8221,7 @@ const qtparam = async (BASEURL, cookie) => {
|
|
|
8018
8221
|
126,
|
|
8019
8222
|
127
|
|
8020
8223
|
];
|
|
8021
|
-
|
|
8022
|
-
logininfo.data.vipStatus === 1 ? isvip = true : isvip = false;
|
|
8224
|
+
const isvip = logininfo.data.vipStatus === 1;
|
|
8023
8225
|
if (isvip) return {
|
|
8024
8226
|
QUERY: `&fnval=4048&fourk=1&${sign}`,
|
|
8025
8227
|
STATUS: "isLogin",
|
|
@@ -8354,7 +8556,7 @@ const fetchBilibili = async (data, cookie, requestConfig) => {
|
|
|
8354
8556
|
...baseRequestConfig,
|
|
8355
8557
|
url: checkStatusUrl
|
|
8356
8558
|
})).data === null) {
|
|
8357
|
-
|
|
8559
|
+
emitLogError("评论区未开放");
|
|
8358
8560
|
return {
|
|
8359
8561
|
code: 404,
|
|
8360
8562
|
message: "评论区未开放",
|
|
@@ -8385,7 +8587,7 @@ const fetchBilibili = async (data, cookie, requestConfig) => {
|
|
|
8385
8587
|
} else isEnd = true;
|
|
8386
8588
|
requestCount++;
|
|
8387
8589
|
if (isEnd || currentComments.length === 0 || !nextPaginationStr) {
|
|
8388
|
-
|
|
8590
|
+
emitLogInfo("已到达评论末尾或无更多评论");
|
|
8389
8591
|
break;
|
|
8390
8592
|
}
|
|
8391
8593
|
}
|
|
@@ -8624,7 +8826,7 @@ const fetchBilibili = async (data, cookie, requestConfig) => {
|
|
|
8624
8826
|
}
|
|
8625
8827
|
}
|
|
8626
8828
|
default:
|
|
8627
|
-
|
|
8829
|
+
emitLogWarn(`未知的B站数据接口:「${data.methodType}」`);
|
|
8628
8830
|
return null;
|
|
8629
8831
|
}
|
|
8630
8832
|
};
|
|
@@ -8660,11 +8862,11 @@ const GlobalGetData = async (type, options, retryCount = 0) => {
|
|
|
8660
8862
|
requestUrl: options.url
|
|
8661
8863
|
};
|
|
8662
8864
|
warningMessage = `
|
|
8663
|
-
|
|
8865
|
+
获取响应数据失败!原因:接口返回内容为空,你的B站ck可能已经失效!
|
|
8664
8866
|
请求类型:「${type}」
|
|
8665
8867
|
请求URL:${options.url}
|
|
8666
8868
|
`;
|
|
8667
|
-
|
|
8869
|
+
emitLogWarn(warningMessage);
|
|
8668
8870
|
const riskError = new Error(Err.errorDescription);
|
|
8669
8871
|
Object.assign(riskError, {
|
|
8670
8872
|
code: "-352",
|
|
@@ -8686,12 +8888,12 @@ const GlobalGetData = async (type, options, retryCount = 0) => {
|
|
|
8686
8888
|
responseCode: result.code
|
|
8687
8889
|
};
|
|
8688
8890
|
warningMessage = `
|
|
8689
|
-
获取响应数据失败!原因:${
|
|
8891
|
+
获取响应数据失败!原因:${errorMessage}
|
|
8690
8892
|
错误代码:${result.code}
|
|
8691
8893
|
请求类型:「${type}」
|
|
8692
8894
|
请求URL:${options.url}
|
|
8693
8895
|
`;
|
|
8694
|
-
|
|
8896
|
+
emitLogWarn(warningMessage);
|
|
8695
8897
|
const apiError = new Error(Err.errorDescription);
|
|
8696
8898
|
Object.assign(apiError, {
|
|
8697
8899
|
code: result.code,
|
|
@@ -9175,15 +9377,6 @@ const kuaishouUtils = {
|
|
|
9175
9377
|
//#endregion
|
|
9176
9378
|
//#region src/platform/xiaohongshu/XiaohongshuApi.ts
|
|
9177
9379
|
/**
|
|
9178
|
-
* 小红书 API 模块 (已废弃)
|
|
9179
|
-
*
|
|
9180
|
-
* 此模块中的 API 已在 v6 版本废弃
|
|
9181
|
-
* 请使用 xiaohongshuFetcher 或 client.xiaohongshu.fetcher 替代
|
|
9182
|
-
*
|
|
9183
|
-
* @module platform/xiaohongshu/XiaohongshuApi
|
|
9184
|
-
* @deprecated v6 已废弃,请使用 fetcher API 替代
|
|
9185
|
-
*/
|
|
9186
|
-
/**
|
|
9187
9380
|
* 创建废弃的 API 存根函数
|
|
9188
9381
|
*/
|
|
9189
9382
|
const createDeprecatedStub = (methodName) => {
|
|
@@ -9986,7 +10179,7 @@ function getApiRoute(platform, methodType) {
|
|
|
9986
10179
|
* 构建后使用 __VERSION__,开发环境从 package.json 读取
|
|
9987
10180
|
*/
|
|
9988
10181
|
const getVersion = () => {
|
|
9989
|
-
return "6.
|
|
10182
|
+
return "6.2.0";
|
|
9990
10183
|
};
|
|
9991
10184
|
const VERSION = getVersion();
|
|
9992
10185
|
/**
|
|
@@ -10033,6 +10226,11 @@ const CreateApp = CreateAmagiApp;
|
|
|
10033
10226
|
/** After instantiation, it can interact with the specified platform API to quickly obtain data. */
|
|
10034
10227
|
const Client = CreateApp;
|
|
10035
10228
|
const amagi = Client;
|
|
10229
|
+
/*!
|
|
10230
|
+
* @ikenxuan/amagi
|
|
10231
|
+
* Copyright(c) 2023 ikenxuan
|
|
10232
|
+
* GPL-3.0 Licensed
|
|
10233
|
+
*/
|
|
10036
10234
|
//#endregion
|
|
10037
10235
|
exports.AdditionalType = AdditionalType;
|
|
10038
10236
|
exports.ApiError = ApiError;
|