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,'
','
'); 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); }