fix(kan360): 360 kan 的 /v1/detail 接口在集数非常多时获取失败 (#336)
Co-authored-by: huangxd- <649924757@qq.com>
This commit is contained in:
1 parent
ee15f5871c
commit
aad97a0f88
1 file changed
+53
-33
+53
-33
@@ -107,6 +107,40 @@ export default class Kan360Source extends BaseSource {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 使用 /v1/detail 分批获取集数(每批最多200集),返回 [{name, url}, ...]
|
||||
async getEpisodesV1(cat, id, site, number) {
|
||||
try {
|
||||
if (!number || Number(number) === 0) return [];
|
||||
const batchSize = 200;
|
||||
let startIdx = 1;
|
||||
const episodes = [];
|
||||
const total = Number(number);
|
||||
while (startIdx <= total) {
|
||||
const endIdx = Math.min(startIdx + batchSize - 1, total);
|
||||
try {
|
||||
const detail = await this.get360Detail(cat, id, site, startIdx, endIdx);
|
||||
if (detail && detail.data && detail.data.allepidetail && detail.data.allepidetail[site]) {
|
||||
for (const it of detail.data.allepidetail[site]) {
|
||||
episodes.push({ name: it.playlink_num, url: it.url });
|
||||
}
|
||||
} else {
|
||||
if (startIdx === 1) return [];
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
log('error', `[360kan] getEpisodesV1 batch ${startIdx}-${endIdx} failed for site ${site}: ${e && e.message ? e.message : e}`);
|
||||
if (startIdx === 1) return [];
|
||||
break;
|
||||
}
|
||||
startIdx = endIdx + 1;
|
||||
}
|
||||
return episodes;
|
||||
} catch (e) {
|
||||
log('error', `getEpisodesV1 error: ${e && e.message ? e.message : e}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 episodesv2 接口获取剧集分集(电视剧/动漫)
|
||||
async getEpisodesV2(cat, entId, site) {
|
||||
try {
|
||||
@@ -121,31 +155,15 @@ export default class Kan360Source extends BaseSource {
|
||||
});
|
||||
|
||||
let data = response.data;
|
||||
|
||||
// 接口可能返回 JSONP(回调包装),尝试剥离
|
||||
if (typeof data === 'string') {
|
||||
const firstParen = data.indexOf('(');
|
||||
const lastParen = data.lastIndexOf(')');
|
||||
if (firstParen !== -1 && lastParen !== -1 && lastParen > firstParen) {
|
||||
const jsonText = data.substring(firstParen + 1, lastParen);
|
||||
try {
|
||||
data = JSON.parse(jsonText);
|
||||
} catch (e) {
|
||||
log('error', `[360kan] getEpisodesV2 JSON parse error: ${e.message}`);
|
||||
return [];
|
||||
}
|
||||
} else {
|
||||
// 如果是纯字符串但非 JSONP,尝试解析为 JSON
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
log('error', `[360kan] getEpisodesV2 unexpected response format`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
log('error', `[360kan] getEpisodesV2 JSON parse error: ${e.message}`);
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!data) return [];
|
||||
}
|
||||
if (!data) return [];
|
||||
|
||||
if (data.code === 0 && Array.isArray(data.data) && data.data.length > 0) {
|
||||
const seriesHTML = data.data[0].seriesHTML || {};
|
||||
@@ -318,18 +336,20 @@ export default class Kan360Source extends BaseSource {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 回退:尝试使用 v1/detail 获取 allepidetail
|
||||
// 回退:使用 v1/detail 分批获取 allepidetail(每批最多 200 集)
|
||||
try {
|
||||
const siteNumber = await this.getNumber(cat, detailId, siteKey);
|
||||
const detail = await this.get360Detail(cat, detailId, siteKey, 1, siteNumber);
|
||||
if (detail && detail.data && detail.data.allepidetail && detail.data.allepidetail[siteKey]) {
|
||||
for (const ep of detail.data.allepidetail[siteKey]) {
|
||||
links.push({
|
||||
name: ep.playlink_num,
|
||||
url: ep.url,
|
||||
title: `【${siteKey}】 第${ep.playlink_num}集`,
|
||||
sort: ep.playlink_num
|
||||
});
|
||||
if (siteNumber && Number(siteNumber) > 0) {
|
||||
const episodes = await this.getEpisodesV1(cat, detailId, siteKey, siteNumber);
|
||||
if (episodes && episodes.length > 0) {
|
||||
for (const ep of episodes) {
|
||||
links.push({
|
||||
name: ep.name,
|
||||
url: ep.url,
|
||||
title: `【${siteKey}】 第${ep.name}集`,
|
||||
sort: ep.name
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
Reference in new issue
Block a user