TBox/JS/189.js
2025-02-01 21:28:00 -05:00

502 lines
17 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

async function fetchShareInfo(url) {
const regex = /https:\/\/cloud\.189\.cn\/t\/(\w+)(?:\?password=(\w+))?|https:\/\/cloud\.189\.cn\/web\/share\?code=(\w+)(?:&password=(\w+))?/;
const match = url.match(regex);
if (!match) {
throw new Error("Invalid URL format");
}
const code = match[1] || match[3];
const password = match[2] || match[4] || '';
console.log(code);
console.log(password);
let fileId;
let files = [];
try {
if (password) {
// 如果 password 不为空,先验证密码
const checkAccessUrl = `https://cloud.189.cn/api/open/share/checkAccessCode.action?noCache=${Math.random()}&shareCode=${code}&accessCode=${password}`;
const checkAccessData = await fetchData(checkAccessUrl);
if (checkAccessData.res_code !== 0) {
throw new Error(
`Password verification failed: ${checkAccessData.res_message}`
);
}
shareId = checkAccessData.shareId;
}
// 获取 shareId 和 fileId
const apiUrl = `https://cloud.189.cn/api/open/share/getShareInfoByCodeV2.action?noCache=${Math.random()}&shareCode=${code}`;
console.log(apiUrl);
const data = await fetchData(apiUrl);
if (!shareId) {
shareId = data.shareId;
}
fileId = data.fileId;
// 递归获取文件和文件夹
await fetchFilesAndFolders(code,fileId, shareId, password, files);
const sortedVideos = sortVideos(files);
const formattedFiles = sortedVideos
.map((file) => `${file.name}$${file.id}`)
.join("#");
return formattedFiles;
} catch (error) {
console.error("Error fetching share info:", error);
throw error;
}
}
function sortVideos(videos) {
return videos.sort((a, b) => {
const extractNumbers = (fileName) => {
const regex = /(\d+)/g;
const matches = fileName.match(regex);
return matches ? matches.map(Number) : [];
};
const numsA = extractNumbers(a.name);
const numsB = extractNumbers(b.name);
for (let i = 0; i < Math.max(numsA.length, numsB.length); i++) {
const numA = numsA[i] || 0;
const numB = numsB[i] || 0;
if (numA !== numB) {
return numA - numB;
}
}
return 0;
});
}
async function fetchFilesAndFolders(code, fileId, shareId, password, files, pageNum = 1, pageSize = 60) {
let listShareUrl = `https://cloud.189.cn/api/open/share/listShareDir.action?noCache=${Math.random()}&pageNum=${pageNum}&pageSize=${pageSize}&fileId=${fileId}&shareDirFileId=${fileId}&isFolder=true&shareId=${shareId}&iconOption=5&orderBy=filename&descending=true&accessCode=`;
if (password) {
listShareUrl += password + '&shareMode=1';
} else {
listShareUrl += password + '&shareMode='+ shareMode;
}
console.log('listShareUrl: '+listShareUrl);
const listShareData = await fetchData(listShareUrl);
// 提取 mediaType 为 3 的文件
listShareData.fileListAO.fileList.forEach(file => {
if (file.mediaType === 3) {
const formattedSize = formatFileSize(file.size);
files.push({
name: `${file.name} [${formattedSize}]`,
id: 'code='+code+'&pwd='+password + '||shareId='+shareId+'&fileId='+file.id.toString()
});
}
});
// 递归遍历文件夹
for (const folder of listShareData.fileListAO.folderList) {
const folderId = folder.id.toString(); // 将 folder.id 转换为字符串
await fetchFilesAndFolders(code, folderId, shareId, password, files, 1, pageSize);
}
// 计算总页数并翻页
const totalPages = Math.ceil(listShareData.fileListAO.count / pageSize);
if (pageNum < totalPages) {
await fetchFilesAndFolders(code, fileId, shareId, password, files, pageNum + 1, pageSize);
}
}
async function fetchData(url) {
const response = await req(url, {
headers: {
'User-Agent': UA,
'Accept': 'application/json;charset=UTF-8',
'Sign-Type': '1',
},
});
let text = await response.text();
//console.log('天翼访问结果:'+text);
return JSON.parse(text);
}
// Step 5: Format file size
function formatFileSize(size) {
const mb = size / (1024 * 1024);
if (mb < 1024) {
return `${mb.toFixed(2)} M`;
} else {
const gb = mb / 1024;
return `${gb.toFixed(2)} G`;
}
}
const webSite = 'https://www.leijing1.com';
const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36';
//let leijingCookie = '变量名称保持不变测试时填入雷鲸小站的cookie发布时在设置中看下访问是否正常';
//let cloud189Cookie = '变量名称保持不变测试时填入天翼云盘cookie发布时在设置中登录天翼云盘';
let shareId;
let shareMode=3;
//let leijingCookie ='';
//let cloud189Cookie ='';
//console.log('运行脚本');
//homeContent();
//categoryContent("42204792950357",1,null);
//detailContent("thread?topicId=18263");
//playerContent("code=zmUbu2IZZNBr&pwd=||shareId=12424112984510&fileId=925381161137919298");
//searchContent("斗罗大陆");
//获取影视列表
async function categoryContent(tid, pg = 1, extend) {
let backData = new RepVideo();
try {
let listUrl = webSite + '/?tagId=' + tid + '&page=' + pg;
console.log(listUrl);
let pro = await req(listUrl, {
headers: {
'User-Agent': UA,
'Cookie': leijingCookie,
},
});
let proData = await pro.text();
console.log('分类结果:'+proData);
const $ = cheerio.load(proData);
let allVideo = $('.topicItem');
let videos = [];
allVideo.each((_, e) => {
if ($(e).find('.cms-lock-solid').length > 0) {
return; // 跳过当前元素
}
if ($(e).find('span.module:contains("问题")').length > 0) {
return; // 跳过当前元素
}
let titleElement = $(e).find('.title a');
let vodUrl = titleElement.attr('href');
let vodName = titleElement.text().trim();
if(tid=='42212287587456'){
vodName = vodName.replace(/【[^】]*】/g, '');
}
const liImageElement = $(e).find('li[data-src]');
let vodPic = liImageElement.attr('data-src');
if (!vodPic) {
let avatarImageElement = $(e).find('.avatarBox img');
vodPic = avatarImageElement.attr('src');
}
if (!vodPic) {
vodPic = 'https://bizaladdin-image.baidu.com/0/pic/-1415092173_198088254_-1820154186.jpg';
}
let postTimeElement = $(e).find('.postTime');
let remarks = postTimeElement.text().trim().replace('发表时间:', '');
let videoDet = new VideoList();
videoDet.vod_id = vodUrl;
videoDet.vod_pic = vodPic;
videoDet.vod_name = vodName;
videoDet.vod_remarks = remarks;
videos.push(videoDet);
})
backData.list = videos;
} catch (error) {
console.error('Error in fetchData:', error);
backData.msg = error.statusText;
}
console.log(JSON.stringify(backData));
return JSON.stringify(backData);
}
//获取影视详情信息
async function detailContent(ids) {
let backData = new RepVideo();
const webUrl = webSite+"/" + ids;
try {
let pro = await req(webUrl, {
headers: {
'User-Agent': UA,
'Cookie': leijingCookie,
},
});
//await toast("正在获取页面详情...", 2);
let proData = await pro.text();
const $ = cheerio.load(proData);
let vod_content = '';
let topicContentImageElement = $('.topicContent img').first();
let vod_pic = topicContentImageElement.attr('src');
if (!vod_pic) {
let authorImageElement = $('.author a img');
vod_pic = authorImageElement.attr('src');
}
if (!vod_pic) {
vod_pic = 'https://bizaladdin-image.baidu.com/0/pic/-1415092173_198088254_-1820154186.jpg';
}
let vod_name = $('.topicBox .title').text().trim();
//console.log(vod_name);
let vod_year = '';
let vod_director = '';
let vod_actor = '';
let vod_area = '';
let linksWithAccessCode = new Set();
proData =文本_取中间(proData,'<div class="left">','<div class="right">');
let regexWithAccessCode = /https:\/\/cloud\.189\.cn\/t\/[a-zA-Z0-9]+[\(]访问码[:][^\s]+[\)]|https:\/\/cloud\.189\.cn\/t\/[a-zA-Z0-9]+|https:\/\/cloud\.189\.cn\/web\/share\?code=[A-Za-z0-9]+[\(]访问码[:][^\s]+[\)]|https:\/\/cloud\.189\.cn\/web\/share\?code=[A-Za-z0-9]+/g;
let matchesWithAccessCode = proData.match(regexWithAccessCode);
if (matchesWithAccessCode) {
matchesWithAccessCode.forEach((link) => {
let cleanLink = link.match(/https:\/\/cloud\.189\.cn\/t\/[a-zA-Z0-9]+|https:\/\/cloud\.189\.cn\/web\/share\?code=[A-Za-z0-9]+/)[0];
let accessCodeMatch = link.match(/[\(]访问码[:]([^\s]+)+[\)]/);
if (accessCodeMatch) {
let accessCode = accessCodeMatch[1];
if(link.includes('/t/')){
cleanLink += `?password=${accessCode}`;
}else{
cleanLink += `&password=${accessCode}`;
}
}
linksWithAccessCode.add(cleanLink);
});
}
// 新增部分:获取 href 中的天翼云盘链接并解码
let hrefRegex = /href="([^"]+)"/g;
let hrefMatches = proData.match(hrefRegex);
if (hrefMatches) {
hrefMatches.forEach((href) => {
let link = href.match(/href="([^"]+)"/)[1];
if (link.startsWith('https://cloud.189.cn/')) {
let decodedLink = decodeURIComponent(link);
let cleanLink = decodedLink.match(/https:\/\/cloud\.189\.cn\/t\/[a-zA-Z0-9]+|https:\/\/cloud\.189\.cn\/web\/share\?code=[A-Za-z0-9]+/)[0];
let accessCodeMatch = decodedLink.match(/[\(]访问码[:]([^\s]+)+[\)]/);
if (accessCodeMatch) {
let accessCode = accessCodeMatch[1];
if (cleanLink.includes('/t/')) {
cleanLink += `?password=${accessCode}`;
} else {
cleanLink += `&password=${accessCode}`;
}
}
linksWithAccessCode.add(cleanLink);
}else if (link.startsWith('https://content.21cn.com/h5/subscrip/index.html#/pages/own-home/index')) {
let shareCodeMatch = link.match(/shareCode=([A-Za-z0-9]+)/);
if (shareCodeMatch) {
shareMode = 5;
let shareCode = shareCodeMatch[1];
let cloudLink = `https://cloud.189.cn/t/${shareCode}`;
linksWithAccessCode.add(cloudLink);
}
}
});
}
// 检查 linksWithAccessCode 是否为空,如果是空的,则进行额外匹配
if (linksWithAccessCode.size === 0) {
let content21cnRegex = /https:\/\/content\.21cn\.com\/h5\/subscrip\/index\.html.*shareCode=([A-Za-z0-9]+)/g;
let content21cnMatches = proData.match(content21cnRegex);
if (content21cnMatches) {
shareMode = 5;
content21cnMatches.forEach((link) => {
let shareCodeMatch = link.match(/shareCode=([A-Za-z0-9]+)/);
if (shareCodeMatch) {
let shareCode = shareCodeMatch[1];
let cloudLink = `https://cloud.189.cn/t/${shareCode}`;
linksWithAccessCode.add(cloudLink);
}
});
}
}
// 处理重复的 code 并优先保留包含 password 的链接
let codeMap = new Map();
for (let link of linksWithAccessCode) {
let codeMatch = link.match(/code=([A-Za-z0-9]+)|t\/([A-Za-z0-9]+)/);
if (codeMatch) {
let code = codeMatch[1] || codeMatch[2]; // 优先使用 code= 的匹配结果,如果没有则使用 t/ 的匹配结果
if (codeMap.has(code)) {
let existingLink = codeMap.get(code);
if (link.includes('password') && !existingLink.includes('password')) {
codeMap.set(code, link);
}
} else {
codeMap.set(code, link);
}
}
}
// 将处理后的链接重新放入 linksWithAccessCode
linksWithAccessCode.clear();
for (let link of codeMap.values()) {
linksWithAccessCode.add(link);
}
//await toast("正在获取网盘剧集...", 2);
// 调用 fetchShareInfo 获取结果
let vod_play_from = '';
let vod_play_url = '';
let index = 1;
for (let link of linksWithAccessCode) {
shareId='';
console.log(link);
let result = await fetchShareInfo(link);
if (result) {
if (vod_play_from) {
vod_play_from += '$$$';
vod_play_url += '$$$';
}
if (linksWithAccessCode.size === 1) {
vod_play_from += '天翼云盘';
} else {
vod_play_from += `天翼云盘${index}`;
}
vod_play_url += result;
index++;
}
}
let detModel = new VideoDetail();
let videos = [];
detModel.vod_year = vod_year;
detModel.vod_director = vod_director;
detModel.vod_actor = vod_actor;
detModel.vod_area = vod_area;
detModel.vod_content = vod_content;
detModel.vod_pic = vod_pic;
detModel.vod_name = vod_name;
detModel.vod_play_from = vod_play_from;
detModel.vod_play_url = vod_play_url;
detModel.vod_id = ids;
videos.push(detModel);
backData.list = videos;
} catch (error) {
console.error('Error in fetchData:', error);
backData.msg = error.statusText;
}
//await toast(JSON.stringify(backData),5);
console.log(JSON.stringify(backData));
return JSON.stringify(backData);
}
//获取首页分类
async function homeContent() {
let backData = new RepVideo();
try {
let list = [];
let allClass = [
{
type_id: '42204681950354',
type_name: '电影',
},
{
type_id: '42204684250355',
type_name: '剧集',
},
{
type_id: '42204792950357',
type_name: '动画动漫',
},
{
type_id: '42210356650363',
type_name: '综艺',
},
{
type_id: '42212287587456',
type_name: '影视原盘',
}
];
//console.log(allClass.length);
allClass.forEach((e) => {
let videoClass = new VideoClass()
videoClass.type_id = e.type_id
videoClass.type_name = e.type_name
list.push(videoClass)
});
backData.class = list;
} catch (error) {
//console.error('Error in fetchData:', error);
backData.msg = error.statusText;
}
console.log(JSON.stringify(backData));
return JSON.stringify(backData);
}
//解析获取播放地址
async function playerContent(vod_id) {
//console.log(vod_id);
let backData = new RepVideoPlayUrl();
let part = vod_id.split('||');
let headers = {'User-Agent': UA,'Cookie': cloud189Cookie,'Referer': 'https://cloud.189.cn/'};
let url = 'https://cloud.189.cn/api/portal/getNewVlcVideoPlayUrl.action?noCache=0.617329187255641&&dt=1&'+part[1]+'&type=4';
await toast("正在获取播放链接...", 2);
try {
const response = await req(url, {
headers: {
'User-Agent': UA,
'Accept': 'application/json;charset=UTF-8',
'Sign-Type': '1',
'Cookie': cloud189Cookie,
},
});
let proData = await response.text();
let jsonObject = JSON.parse(proData);
backData.url = jsonObject.normal.url;
if (backData.url) {
await toast("播放链接获取成功,尝试播放...", 2);
}
} catch (error) {
let errData = await error.text();
await toast("解析播放链接失败:"+ errData, 5);
console.error('Error in fetchData:', errData);
backData.msg = error.statusText;
}
backData.playUrl = '';
backData.parse = 1;
backData.header = headersToString(headers);
//console.log(JSON.stringify(backData));
return JSON.stringify(backData);
}
async function searchContent(keyword) {
let backData = new RepVideo();
try {
let listUrl = webSite + `/search?keyword=${keyword}`
console.log(listUrl);
let pro = await req(listUrl, {
headers: {
'User-Agent': UA,
'Cookie': leijingCookie,
},
});
let proData = await pro.text();
const $ = cheerio.load(proData);
let allVideo = $('.topicItem');
let videos = [];
allVideo.each((_, e) => {
if ($(e).find('.cms-lock-solid').length > 0) {
return; // 跳过当前元素
}
if ($(e).find('span.module:contains("问题")').length > 0) {
return; // 跳过当前元素
}
let titleElement = $(e).find('.title a');
let vodUrl = titleElement.attr('href');
let vodName = titleElement.text().trim();
const liImageElement = $(e).find('li[data-src]');
let vodPic = liImageElement.attr('data-src');
if (!vodPic) {
let avatarImageElement = $(e).find('.avatarBox img');
vodPic = avatarImageElement.attr('src');
}
if (!vodPic) {
vodPic = 'https://bizaladdin-image.baidu.com/0/pic/-1415092173_198088254_-1820154186.jpg';
}
let postTimeElement = $(e).find('.postTime');
let remarks = postTimeElement.text().trim().replace('发表时间:', '');
let videoDet = new VideoList();
videoDet.vod_id = vodUrl;
videoDet.vod_pic = vodPic;
videoDet.vod_name = vodName;
videoDet.vod_remarks = remarks;
videos.push(videoDet);
})
backData.list = videos;
} catch (error) {
console.error('Error in fetchData:', error);
backData.msg = error.statusText;
}
console.log(JSON.stringify(backData));
return JSON.stringify(backData);
}