Skip to content

Commit 7996e8d

Browse files
authored
fix(bilibili): 修复集数倒序问题并规范化HTML实体解码 (huangxd-#342)
- 修复:将集数排序基准从易受干扰的标题文本切换为B站底层数据主键(ep.id/cid),进行绝对数值升序排列,彻底解决因不规则标题(如精华版)破坏排序算法导致的集数倒序问题。 - 重构:移除各处零散的内联HTML实体解码字典,将命名实体解码逻辑统一收敛下沉至公共工具类 `codec-util.js`,提升代码规范度与复用性。
1 parent cda5ba5 commit 7996e8d

2 files changed

Lines changed: 28 additions & 31 deletions

File tree

danmu_api/sources/bilibili.js

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import BaseSource from './base.js';
22
import { globals } from '../configs/globals.js';
33
import { log } from "../utils/log-util.js";
44
import { httpGet, httpGetWithStreamCheck } from "../utils/http-util.js";
5-
import { parseDanmakuBase64, md5, convertToAsciiSum } from "../utils/codec-util.js";
5+
import { parseDanmakuBase64, md5, convertToAsciiSum, decodeHtmlEntities } from "../utils/codec-util.js";
66
import { generateValidStartDate } from "../utils/time-util.js";
77
import { addAnime, removeEarliestAnime } from "../utils/cache-util.js";
88
import { titleMatches, getExplicitSeasonNumber, extractSeasonNumberFromAnimeTitle } from "../utils/common-util.js";
@@ -197,23 +197,13 @@ export default class BilibiliSource extends BaseSource {
197197
// 忽略年份解析错误
198198
}
199199

200-
// 清理标题
201-
const cleanedTitle = (item.title || "")
202-
.replace(/<[^>]+>/g, '') // 移除 HTML 标签
203-
.replace(/&[^;]+;/g, match => { // 解码 HTML 实体
204-
const entities = { '&lt;': '<', '&gt;': '>', '&amp;': '&', '&quot;': '"', '&#39;': "'" };
205-
return entities[match] || match;
206-
})
200+
// 清理标题,移除 HTML 标签并解码 HTML 实体
201+
const cleanedTitle = decodeHtmlEntities((item.title || "").replace(/<[^>]+>/g, ''))
207202
.replace(/:/g, ':')
208203
.trim();
209204

210-
// 清洗原标题
211-
const cleanedOrgTitle = (item.org_title || "")
212-
.replace(/<[^>]+>/g, '')
213-
.replace(/&[^;]+;/g, match => {
214-
const entities = { '&lt;': '<', '&gt;': '>', '&amp;': '&', '&quot;': '"', '&#39;': "'" };
215-
return entities[match] || match;
216-
})
205+
// 清洗原标题,移除 HTML 标签并解码 HTML 实体
206+
const cleanedOrgTitle = decodeHtmlEntities((item.org_title || "").replace(/<[^>]+>/g, ''))
217207
.trim();
218208

219209
const resultItem = {
@@ -684,17 +674,13 @@ export default class BilibiliSource extends BaseSource {
684674
return {
685675
name: realVal,
686676
url: linkUrl,
687-
title: `【bilibili1】 ${displayTitle.trim()}`
677+
title: `【bilibili1】 ${displayTitle.trim()}`,
678+
_id: parseInt(epId, 10) || 0
688679
};
689680
});
690681

691-
// 按照提取出的 name (真实集号) 进行升序排列
692-
links.sort((a, b) => {
693-
const numA = parseFloat(a.name);
694-
const numB = parseFloat(b.name);
695-
if (!isNaN(numA) && !isNaN(numB)) return numA - numB;
696-
return 0;
697-
});
682+
// 依据底层数据主键 ep_id 进行时间序列升序排列
683+
links.sort((a, b) => a._id - b._id);
698684

699685
log("info", `[Bilibili] 直接使用搜索结果中的 ${links.length} 集分集`);
700686
} else {
@@ -712,9 +698,13 @@ export default class BilibiliSource extends BaseSource {
712698
return {
713699
name: `${index + 1}`,
714700
url: linkUrl,
715-
title: `【bilibili1】 ${ep.title}`
701+
title: `【bilibili1】 ${ep.title}`,
702+
_id: parseInt(ep.id, 10) || 0
716703
};
717704
});
705+
706+
// 依据底层数据主键 ep_id 进行时间序列升序排列
707+
links.sort((a, b) => a._id - b._id);
718708
}
719709

720710
if (links.length === 0) return;
@@ -1198,8 +1188,8 @@ export default class BilibiliSource extends BaseSource {
11981188
.map(i => ({
11991189
provider: "bilibili",
12001190
mediaId: i.season_id ? `ss${i.season_id}` : (i.uri.match(/season\/(\d+)/)?.[1] ? `ss${i.uri.match(/season\/(\d+)/)[1]}` : ""),
1201-
title: (i.title||"").replace(/<[^>]+>/g,'').trim(),
1202-
org_title: (i.org_title||"").replace(/<[^>]+>/g,'').trim(),
1191+
title: decodeHtmlEntities((i.title||"").replace(/<[^>]+>/g,'')).trim(),
1192+
org_title: decodeHtmlEntities((i.org_title||"").replace(/<[^>]+>/g,'')).trim(),
12031193
type: this._extractMediaType(i.season_type_name),
12041194
year: i.ptime ? new Date(i.ptime*1000).getFullYear() : null,
12051195
imageUrl: i.cover||i.pic||"",
@@ -1243,11 +1233,11 @@ export default class BilibiliSource extends BaseSource {
12431233
provider: "bilibili",
12441234
mediaId: i.season_id ? `ss${i.season_id}` : "",
12451235
mdId: i.media_id ? `md${i.media_id}` : null,
1246-
title: (i.title||"").replace(/<[^>]+>/g,'').trim(),
1247-
org_title: (i.org_title || "").replace(/<[^>]+>/g,'').replace(/&[^;]+;/g, match => { const entities = { '&lt;': '<', '&gt;': '>', '&amp;': '&', '&quot;': '"', '&#39;': "'" }; return entities[match] || match; }).trim(),
1236+
title: decodeHtmlEntities((i.title||"").replace(/<[^>]+>/g,'')).trim(),
1237+
org_title: decodeHtmlEntities((i.org_title || "").replace(/<[^>]+>/g,'')).trim(),
12481238
type: this._extractMediaType(i.season_type_name),
1249-
year: i.pubtime?new Date(i.pubtime*1000).getFullYear():null,
1250-
imageUrl: i.cover||null,
1239+
year: i.pubtime?new Date(i.pubtime*1000).getFullYear():null,
1240+
imageUrl: i.cover||null,
12511241
episodeCount: i.ep_size||0,
12521242
_eps: i.eps,
12531243
isOversea: true

danmu_api/utils/codec-util.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,8 +744,15 @@ function fromCodePoint(codePoint) {
744744
* @returns {string} 转换后的字符串
745745
*/
746746
export function decodeHtmlEntities(str) {
747+
if (!str) return str;
748+
const namedEntities = { '&lt;': '<', '&gt;': '>', '&amp;': '&', '&quot;': '"', '&apos;': "'" };
749+
750+
// 处理命名HTML实体
751+
return str.replace(/&[a-zA-Z]+;/g, match => {
752+
return namedEntities[match] || match;
753+
})
747754
// 处理十进制HTML实体 &#12345;
748-
return str.replace(/&#(\d+);/g, (match, num) => {
755+
.replace(/&#(\d+);/g, (match, num) => {
749756
return fromCodePoint(parseInt(num, 10));
750757
})
751758
// 处理十六进制HTML实体 &#x123A;

0 commit comments

Comments
 (0)