  |  |   |    | 
                         
                         
                         
- /*
 
 -    欢迎使用AiWork安卓自动化IDE
 
  
- */
 
  
- // 定义主函数
 
 - function downloadLanzouFile(url, saveFilePath, maxRetries) {
 
 -     // 设置默认参数
 
 -     if (maxRetries === undefined) {
 
 -         maxRetries = 5;  // 增加默认重试次数
 
 -     }
 
 -     
 
 -     var http = new okHttp();
 
 -     var domains = ["wwt.lanzouu.com", "wwt.lanzoui.com", "wwt.lanzoux.com"];  // 备用域名
 
 -     var currentDomain = domains[0];
 
 -     var startTime = new Date().getTime();
 
 -     
 
 -     function sleep(ms) {
 
 -         java.lang.Thread.sleep(ms);
 
 -     }
 
 -     
 
 -     // 指数退避算法计算等待时间
 
 -     function getWaitTime(retryCount) {
 
 -         return Math.min(2000 * Math.pow(1.5, retryCount), 10000);  // 最长等待10秒
 
 -     }
 
 -     
 
 -     function formatTime(ms) {
 
 -         if (ms < 1000) return ms + "毫秒";
 
 -         return Math.floor(ms / 1000) + "秒";
 
 -     }
 
 -     
 
 -     for (var retryCount = 0; retryCount < maxRetries; retryCount++) {
 
 -         if (retryCount > 0) {
 
 -             var waitTime = getWaitTime(retryCount);
 
 -             printl("第" + (retryCount + 1) + "次尝试下载...(等待" + formatTime(waitTime) + ")");
 
 -             
 
 -             // 每次重试时尝试切换域名
 
 -             currentDomain = domains[retryCount % domains.length];
 
 -             printl("切换到域名: " + currentDomain);
 
 -             
 
 -             sleep(waitTime);
 
 -         }
 
 -         
 
 -         try {
 
 -             printl("开始下载过程...");
 
 -             
 
 -             // 获取初始页面
 
 -             printl("正在获取初始页面...");
 
 -             var processedUrl = url.replace(/wwt\.lanzo[a-z]{1,2}\.com/, currentDomain);
 
 -             var r = http.get(processedUrl);
 
 -             
 
 -             // 检查是否包含错误信息
 
 -             if (r.includes("文件不存在") || r.includes("已被删除")) {
 
 -                 throw "文件不存在或已被删除";
 
 -             }
 
 -             
 
 -             // 获取跳转路径
 
 -             var regex = /\/fn\?[\w-]+/g;
 
 -             var fnPathMatch = r.match(regex);
 
 -             if (!fnPathMatch) {
 
 -                 throw "无法获取跳转路径";
 
 -             }
 
 -             var fnPath = fnPathMatch[0];
 
 -             printl("获取跳转路径:", fnPath);
 
  
-             // 获取二级页面
 
 -             var r2 = http.get("https://" + currentDomain + fnPath);
 
 -             printl("已获取二级页面");
 
 -             
 
 -             // 检查二级页面是否有效
 
 -             if (r2.includes("文件不存在") || r2.includes("已被删除")) {
 
 -                 throw "文件不存在或已被删除";
 
 -             }
 
  
-             // 使用更精确的正则匹配sign
 
 -             var signMatch = r2.match(/var wp_sign = '([^']+)';/);
 
 -             if (!signMatch) {
 
 -                 throw "无法提取签名参数";
 
 -             }
 
 -             var sign = signMatch[1];
 
 -             printl("获取签名:", sign);
 
  
-             // 匹配ajax请求路径
 
 -             var ajaxPathMatch = r2.match(/url : '(\/ajaxm\.php\?file=\d+)'/);
 
 -             if (!ajaxPathMatch) {
 
 -                 throw "无法提取ajax路径";
 
 -             }
 
 -             var ajaxUrl = "https://" + currentDomain + ajaxPathMatch[1];
 
 -             printl("构造请求地址:", ajaxUrl);
 
  
-             // 配置请求头
 
 -             http.clearHeader();
 
 -             http.setHeader('Referer', "https://" + currentDomain + fnPath);
 
 -             http.setHeader('User-Agent', "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36");
 
 -             http.setHeader('X-Requested-With', 'XMLHttpRequest');
 
 -             http.setHeader('Origin', "https://" + currentDomain);
 
 -             http.setHeader('Content-Type', 'application/x-www-form-urlencoded');
 
 -             http.setHeader('Accept', 'application/json, text/javascript, */*; q=0.01');
 
 -             http.setHeader('Accept-Language', 'zh-CN,zh;q=0.9,en;q=0.8');
 
 -             http.setHeader('Connection', 'keep-alive');
 
 -             http.setHeader('Cache-Control', 'no-cache');
 
 -             http.setHeader('Pragma', 'no-cache');
 
  
-             // 构造POST数据
 
 -             var data = new map();
 
 -             data.add('action', 'downprocess');
 
 -             data.add('signs', sign.substring(0, 5));
 
 -             data.add('sign', sign);
 
 -             data.add('websign', '');
 
 -             data.add('websignkey', '61rx');
 
 -             data.add('ves', 1);
 
  
-             // 发送POST请求
 
 -             var postRes = http.post(ajaxUrl, data);
 
 -             
 
 -             // 检查是否返回了错误页面
 
 -             if (postRes.includes("<!DOCTYPE html>") || postRes.includes("405")) {
 
 -                 throw "服务器返回了错误页面,需要重试";
 
 -             }
 
 -             
 
 -             try {
 
 -                 var postData = JSON.parse(postRes);
 
 -                 
 
 -                 if (!postData.dom || !postData.url) {
 
 -                     throw "无法获取下载信息";
 
 -                 }
 
 -                 
 
 -                 // 获取下载地址
 
 -                 var downloadUrl = postData.dom + "/file/" + postData.url;
 
 -                 printl("初始下载地址:", downloadUrl);
 
 -                 
 
 -                 // 尝试直接访问下载地址,设置跟随重定向
 
 -                 printl("尝试直接访问下载地址...");
 
 -                 http.clearHeader();
 
 -                 http.setHeader('User-Agent', "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36");
 
 -                 http.setHeader('Accept', "*/*");
 
 -                 http.setHeader('Accept-Language', "zh-CN,zh;q=0.9,en;q=0.8");
 
 -                 http.setHeader('Referer', "https://" + currentDomain + "/");
 
 -                 http.setHeader('Connection', 'keep-alive');
 
 -                 
 
 -                 // 直接尝试下载文件
 
 -                 printl("开始下载文件...");
 
 -                 var downloadStartTime = new Date().getTime();
 
 -                 http.downloadFile(downloadUrl, saveFilePath);
 
 -                 var downloadEndTime = new Date().getTime();
 
 -                 var downloadTime = downloadEndTime - downloadStartTime;
 
 -                 
 
 -                 printl("文件下载完成,耗时: " + formatTime(downloadTime));
 
 -                 
 
 -                 // 检查文件大小
 
 -                 try {
 
 -                     var file = new java.io.File(saveFilePath);
 
 -                     var fileSize = file.length();
 
 -                     printl("文件大小: " + formatFileSize(fileSize));
 
 -                     
 
 -                     if (fileSize < 1024) {  // 如果文件小于1KB,可能是错误页面
 
 -                         printl("警告: 文件大小异常小,可能下载不完整");
 
 -                     }
 
 -                 } catch (e) {
 
 -                     printl("无法获取文件信息: " + e);
 
 -                 }
 
 -                 
 
 -                 var totalTime = new Date().getTime() - startTime;
 
 -                 printl("总耗时: " + formatTime(totalTime));
 
 -                 return true; // 下载成功,退出重试循环
 
 -                 
 
 -             } catch (jsonError) {
 
 -                 printl("解析JSON失败: " + jsonError + ", 响应内容: " + postRes.substring(0, 100));
 
 -                 throw "无法解析服务器响应";
 
 -             }
 
 -             
 
 -         } catch (error) {
 
 -             printl("当前尝试出错: " + error);
 
 -             if (retryCount === maxRetries - 1) {
 
 -                 // 最后一次尝试也失败了
 
 -                 printl("所有重试都失败了");
 
 -                 return false;
 
 -             }
 
 -             // 否则继续下一次重试
 
 -             continue;
 
 -         }
 
 -     }
 
 -     return false;
 
 - }
 
  
- // 格式化文件大小
 
 - function formatFileSize(bytes) {
 
 -     if (bytes < 1024) return bytes + " B";
 
 -     else if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + " KB";
 
 -     else if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(2) + " MB";
 
 -     else return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GB";
 
 - }
 
  
- // 使用示例
 
 - var url = "https://wwwgmg.lanzn.com/tomatoOCR";
 
 - var saveFilePath = "/sdcard/Download/TomatoOCR.apk";
 
 - var result = downloadLanzouFile(url, saveFilePath);
 
  
- if (result) {
 
 -     printl("文件成功下载到: " + saveFilePath);
 
 - } else {
 
 -     printl("文件下载失败");
 
 - }
 
  复制代码这段代码是一个用于从蓝奏云(Lanzou)下载文件的自动化工具 脚本,主要基于JavaScript编写,并且是在一个安卓自动化环境中运行的,例如使用AiWork这样的自动化IDE。代码中定义了一个主要的函数downloadLanzouFile,它接受三个参数:文件的URL地址url,保存文件的路径saveFilePath,以及最大重试次数maxRetries(如果未提供,函数默认设置为5次)。  代码的主要功能和步骤如下: 
- 定义了蓝奏云的备用域名列表,以便在遇到某个域名无法访问时进行切换。
 - 定义了一个sleep函数用于线程休眠,以便在重试之间等待一段时间。
 - 定义了两个辅助函数:getWaitTime用于计算每次重试时的等待时间,采用指数退避算法;formatTime用于将毫秒数格式化为更易读的时间格式。
 
 
 
  
- 使用一个for循环来实现下载的重试机制,每次遇到错误时会增加重试次数。
 - 在每次重试之前,通过sleep函数等待一段时间,时间会随着重试次数增加而增加。
 - 使用okHttp库来发送HTTP请求,首先获取初始页面内容。
 - 解析初始页面以获取跳转路径,并访问二级页面以获取文件的签名参数sign。
 - 通过解析二级页面的HTML内容,获取用于下载文件的AJAX请求URL。
 - 配置HTTP请求头,模拟浏览器行为,以获取正确的下载地址。
 - 构造POST请求的数据,包括签名信息等,发送POST请求以获取下载地址。
 - 下载文件并通过formatFileSize函数格式化输出文件大小。
 - 检查文件大小是否异常小,以判断文件是否下载完整。
 
 
 
  
- 如果在下载过程中遇到任何错误(如文件不存在、服务器返回错误页面、无法解析JSON等),会被捕获并输出错误信息。
 - 如果在最大重试次数内仍未能成功下载文件,函数将返回false,表示下载失败。
 
 
 
  
- formatFileSize函数用于将文件大小从字节转换为KB、MB或GB,并保留两位小数。
 
 
 
  
- 提供了一个使用示例,展示了如何调用downloadLanzouFile函数来下载文件,并根据返回结果判断文件是否成功下载。
 
 
  
 
  |  |    |  |   |  
  |