yz-yuki-plugin 2.0.10-2 → 2.0.10-5
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/CHANGELOG.md +1 -0
- package/defaultConfig/bilibili/config.yaml +3 -3
- package/lib/apps/bilibili.js +4 -0
- package/lib/models/bilibili/bilibili.main.api.js +21 -0
- package/lib/models/bilibili/bilibili.main.get.web.data.js +109 -4
- package/lib/models/bilibili/bilibili.risk.cookie.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -15,9 +15,9 @@ checkDynamicCD: '*/23 * * * *'
|
|
|
15
15
|
# 请求头 User-Agent 列表。如出现 -352 风控,可尝试更换请求头,请根据需要自行添加或修改。
|
|
16
16
|
# 可设置多个请求头,每次重启后会随机选择一个。获取方法请浏览器自行搜索。
|
|
17
17
|
userAgentList:
|
|
18
|
-
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
19
|
-
#- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:
|
|
20
|
-
#- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
|
|
18
|
+
- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36'
|
|
19
|
+
#- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:156.0) Gecko/20100101 Firefox/156.0'
|
|
20
|
+
#- 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36 Edg/152.0.0.0'
|
|
21
21
|
|
|
22
22
|
# 筛选何时发布的动态,单位为秒,默认7200秒即2小时,即以当前时间为基准,筛选过去2小时内的发布动态,并推送。
|
|
23
23
|
# 取值范围:3600-36000秒,即过去的1-10h。应大于checkDynamicCD的周期。
|
package/lib/apps/bilibili.js
CHANGED
|
@@ -528,6 +528,10 @@ message.use(async (e) => {
|
|
|
528
528
|
if (videoIDMatch[2]) {
|
|
529
529
|
// 匹配 b23.tv/ 后面的部分
|
|
530
530
|
const bvidStr = await new BilibiliWebDataFetcher(e).getBVIDByShortUrl(videoIDMatch[2]);
|
|
531
|
+
if (bvidStr === false) {
|
|
532
|
+
e.reply('遭遇风控或意外,短链解析失败,无法获取BVID~');
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
531
535
|
videoID = { bvid: bvidStr };
|
|
532
536
|
}
|
|
533
537
|
else if (videoIDMatch[4].startsWith('av')) {
|
|
@@ -43,6 +43,8 @@ class BiliApi {
|
|
|
43
43
|
biliVideoInfoWbi: `https://api.bilibili.com/x/web-interface/wbi/view`,
|
|
44
44
|
//短链
|
|
45
45
|
biliShortVideoUrl: `https://b23.tv/`,
|
|
46
|
+
//短链412解控接口
|
|
47
|
+
biliCapchaCheck: 'https://security.bilibili.com/th/captcha/cc/check',
|
|
46
48
|
biliLiveStatus: 'https://api.live.bilibili.com/room/v1/Room/get_status_info_by_uids',
|
|
47
49
|
biliCard: 'https://api.bilibili.com/x/web-interface/card',
|
|
48
50
|
biliStat: 'https://api.bilibili.com/x/relation/stat',
|
|
@@ -127,6 +129,25 @@ class BiliApi {
|
|
|
127
129
|
'User-Agent': this.USER_AGENT
|
|
128
130
|
};
|
|
129
131
|
}
|
|
132
|
+
get BILIBILI_CAPTCHA_CHECK_HEADERS() {
|
|
133
|
+
return {
|
|
134
|
+
'Accept': '*/*',
|
|
135
|
+
'Accept-Encoding': 'gzip, deflate, br, zstd',
|
|
136
|
+
'Accept-Language': 'zh-CN,en-US;q=0.5',
|
|
137
|
+
'Connection': 'keep-alive',
|
|
138
|
+
'Content-type': 'application/x-www-form-urlencoded',
|
|
139
|
+
'Host': 'security.bilibili.com',
|
|
140
|
+
'Origin': 'https://www.bilibili.com',
|
|
141
|
+
'Pragma': 'no-cache',
|
|
142
|
+
'Referer': 'https://www.bilibili.com/',
|
|
143
|
+
'Sec-Fetch-Dest': 'empty',
|
|
144
|
+
'Sec-Fetch-Mode': 'cors',
|
|
145
|
+
'Sec-Fetch-Site': 'same-site',
|
|
146
|
+
'Sec-GPC': '1',
|
|
147
|
+
'TE': 'trailers',
|
|
148
|
+
'User-Agent': this.USER_AGENT
|
|
149
|
+
};
|
|
150
|
+
}
|
|
130
151
|
/**返回GatWay payload */
|
|
131
152
|
async BILIBILI_BROWSER_DATA(_uuid) {
|
|
132
153
|
return {
|
|
@@ -6,6 +6,7 @@ import axioss from 'axios';
|
|
|
6
6
|
import { wrapper } from 'axios-cookiejar-support';
|
|
7
7
|
import lodash from 'lodash';
|
|
8
8
|
import * as tough from 'tough-cookie';
|
|
9
|
+
import crypto from 'crypto';
|
|
9
10
|
|
|
10
11
|
const axios = wrapper(axioss);
|
|
11
12
|
class BilibiliWebDataFetcher {
|
|
@@ -220,10 +221,114 @@ class BilibiliWebDataFetcher {
|
|
|
220
221
|
timeout: 15000,
|
|
221
222
|
headers
|
|
222
223
|
});
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
if (res.status === 200) {
|
|
225
|
+
const htmlContent = await res.data;
|
|
226
|
+
const htmlContentRegex = /property="og:url"\s*content="https:\/\/www.bilibili.com\/video\/(BV[a-zA-Z0-9]+)\/">/;
|
|
227
|
+
const BVID = htmlContent.match(htmlContentRegex)?.[1];
|
|
228
|
+
if (BVID) {
|
|
229
|
+
logger.info(`哔哩视频解析:status 200 解析短链成功,BVID: ${BVID}`);
|
|
230
|
+
return `${BVID}`;
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
logger.error('哔哩视频解析:status 200 正则不匹配,无法获取BVID');
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else if (res.status === 302) {
|
|
238
|
+
const locationHeader = res.headers['location'];
|
|
239
|
+
const bvidRegex = /\/video\/(BV[a-zA-Z0-9]+)/;
|
|
240
|
+
const bvidMatch = locationHeader?.match(bvidRegex)?.[1];
|
|
241
|
+
if (bvidMatch) {
|
|
242
|
+
logger.info(`哔哩视频解析:status 302 解析短链成功,BVID: ${bvidMatch}`);
|
|
243
|
+
return `${bvidMatch}`;
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
logger.error('哔哩视频解析:status 302 正则不匹配,无法获取BVID');
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else if (res.status === 412) {
|
|
251
|
+
const X_BILI_SEC_TOKEN = res.headers['set-cookie']
|
|
252
|
+
?.find(c => c.includes('X-BILI-SEC-TOKEN='))
|
|
253
|
+
?.split(';')[0]
|
|
254
|
+
.split('=')[1];
|
|
255
|
+
let decodedResult = null; // 显式设为可空
|
|
256
|
+
if (X_BILI_SEC_TOKEN) {
|
|
257
|
+
const base64_text = X_BILI_SEC_TOKEN.split('.')[1];
|
|
258
|
+
const decoded = Buffer.from(base64_text + '==', 'base64').toString('utf8');
|
|
259
|
+
const obj = JSON.parse(decoded); //{"q":"xxxxx","r":"xxxxx","ip":"xx.xx.xx.xx","fp":"xxx","verity":0,"type":"1","exp":1788276102,"iat":1788272502}
|
|
260
|
+
const limit = 0x4c4b40;
|
|
261
|
+
for (let i = 0; i < limit; i++) {
|
|
262
|
+
const hash = crypto
|
|
263
|
+
.createHash('sha256')
|
|
264
|
+
.update(obj.q + String(i))
|
|
265
|
+
.digest('hex');
|
|
266
|
+
if (hash === obj.r) {
|
|
267
|
+
decodedResult = i;
|
|
268
|
+
break; // 找到后立即跳出循环,节省时间
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// 只有找到了结果才发送请求
|
|
272
|
+
if (decodedResult !== null) {
|
|
273
|
+
const capchaCheckRes = await axios.post(BiliApi.BILIBIL_API.biliCapchaCheck, { token: X_BILI_SEC_TOKEN, result: decodedResult }, { headers: BiliApi.BILIBILI_CAPTCHA_CHECK_HEADERS });
|
|
274
|
+
const capchaCheckResData = capchaCheckRes.data;
|
|
275
|
+
if (capchaCheckResData.code === 0) {
|
|
276
|
+
const afterCapchaCheckHeaders = lodash.merge(BiliApi.BILIBILI_DYNAMIC_SPACE_HEADERS, {
|
|
277
|
+
Cookie: mark === 'localCk' ? `${bili_ticket};${cookie}` : undefined
|
|
278
|
+
}, {
|
|
279
|
+
Cookie: `X-BILI-SEC-TOKEN=${capchaCheckResData.message}`
|
|
280
|
+
});
|
|
281
|
+
const res = await axios.get(url, {
|
|
282
|
+
jar: ck, // 仅在非 localCk 时传递 jar
|
|
283
|
+
timeout: 15000,
|
|
284
|
+
headers: afterCapchaCheckHeaders
|
|
285
|
+
});
|
|
286
|
+
if (res.status === 200) {
|
|
287
|
+
const htmlContent = await res.data;
|
|
288
|
+
const htmlContentRegex = /property="og:url"\s*content="https:\/\/www.bilibili.com\/video\/(BV[a-zA-Z0-9]+)\/">/;
|
|
289
|
+
const BVID = htmlContent.match(htmlContentRegex)?.[1];
|
|
290
|
+
if (BVID) {
|
|
291
|
+
logger.info(`哔哩视频解析:status 412-200 解析短链成功,BVID: ${BVID}`);
|
|
292
|
+
return `${BVID}`;
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
logger.error('哔哩视频解析:status 412-200 正则不匹配,无法获取BVID');
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
else if (res.status === 302) {
|
|
300
|
+
const locationHeader = res.headers['location'];
|
|
301
|
+
const bvidRegex = /\/video\/(BV[a-zA-Z0-9]+)/;
|
|
302
|
+
const bvidMatch = locationHeader?.match(bvidRegex)?.[1];
|
|
303
|
+
if (bvidMatch) {
|
|
304
|
+
logger.info(`哔哩视频解析:status 412-302 解析短链成功,BVID: ${bvidMatch}`);
|
|
305
|
+
return `${bvidMatch}`;
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
logger.error('哔哩视频解析:status 412-302 正则不匹配,无法获取BVID');
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
logger.error('哔哩视频解析:解风控失败,短链解析失败,无法获取BVID');
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
else if (capchaCheckResData.code === -1) {
|
|
318
|
+
logger.error('哔哩视频解析:解风控失败,风控方法可能已更新');
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
logger.error('哔哩视频解析:解风控失败,未找到匹配的验证码值');
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
logger.error('哔哩视频解析:遭遇风控或意外,短链解析失败,无法获取BVID');
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
227
332
|
}
|
|
228
333
|
}
|
|
229
334
|
|
|
@@ -478,7 +478,7 @@ class BiliRiskCookie {
|
|
|
478
478
|
* 简单策略:优先从 Redis 读取长期 cookie(如 SESSDATA),若缺失则触发完整获取流程
|
|
479
479
|
* */
|
|
480
480
|
async ensureLoginCookies(jar) {
|
|
481
|
-
// 常见域名为 .
|
|
481
|
+
// 常见域名为 .bilibili.com 或 bilibili.com,根据实际情况检查
|
|
482
482
|
const SESSDATA_Key1 = `${this.prefix}:.bilibili.com:SESSDATA`;
|
|
483
483
|
const SESSDATA_Key2 = `${this.prefix}:bilibili.com:SESSDATA`;
|
|
484
484
|
const isLogin = (await Redis.get(SESSDATA_Key1)) || (await Redis.get(SESSDATA_Key2));
|