信息发布软件,b2b软件,广告发布软件

 找回密码
 立即注册
搜索
查看: 1|回复: 0
打印 上一主题 下一主题

[宣传软件网站动态] 元宝截图B站验证码示例测试

[复制链接]

791

主题

875

帖子

5608

积分

积分
5608

资讯缩略图:

资讯发布日期:2026-07-16

资讯发布简介:元宝截图B站验证码示例测试

资讯关键词:元宝截图B站验证码示例测试

资讯所属分类:IT资讯 SEO资讯 

联系:

① 本信息收集于网络,如有不对的地方欢迎联系我纠正!
② 本信息免费收录,不存在价格的问题!
③ 如果您的网站也想这样出现在这里,请您加好友情链接,我当天会审核通过!

④友情链接关键字:软件网站分类目录 网址:http://www.postbbs.com/

资讯详细描述
元宝截图B站验证码示例测试
元宝截图B站验证码示例测试 b2b软件
  1. // AIWROK 自动化流程:截图B站验证码 → 启动元宝 → 发送截图询问拖动距离 → 采集回答 → 切回B站拖动滑块
  2. // 包名:com.tencent.hunyuan.app.chat(元宝)
  3. //
  4. // 使用说明:
  5. //   1. 在B站验证码页面运行脚本
  6. //   2. 脚本自动截图并发送给元宝识别
  7. //   3. 解析元宝返回的拖动距离,切回B站拖动滑块

  8. print.log("===== 元宝识别验证码拖动B站流程启动 =====");
  9. print.time();

  10. // ========== 配置区 ==========
  11. var 元宝包名 = "com.tencent.hunyuan.app.chat";
  12. var B站包名 = "tv.danmaku.bili";
  13. var 截图保存路径 = "/sdcard/验证码截图.png";

  14. var 等待回答超时秒 = 20;
  15. var 回答输出等待秒 = 5;
  16. var 滑块校准系数 = 1.0;

  17. var 提问话术 = "请帮我分析这张图片,告诉我左边的方块需要向右移动多少像素才能和右边的缺口对齐,只输出数字";

  18. // ========== 获取设备信息 ==========
  19. var 屏幕宽 = screen.getScreenWidth();
  20. var 屏幕高 = screen.getScreenHeight();
  21. var 验证码滑块距离 = null;
  22. print.log("屏幕尺寸:" + 屏幕宽 + " x " + 屏幕高);
  23. print.log("代理状态:" + (agent.isOpen() ? "已开启" : "未开启"));

  24. // ========== 工具函数 ==========

  25. function 获取UI() {
  26.     var xml = agent.getXml();
  27.     return "" + xml;
  28. }

  29. function 字符串长度(s) {
  30.     var str = "" + s;
  31.     return str.length;
  32. }

  33. function 解码HTML实体(s) {
  34.     var str = "" + s;
  35.     str = str.replace(/
  36. /g, "\n");
  37.     str = str.replace(/
  38. /g, "\r");
  39.     str = str.replace(/        /g, "\t");
  40.     str = str.replace(/'/g, "'");
  41.     str = str.replace(/"/g, '"');
  42.     str = str.replace(/"/g, '"');
  43.     str = str.replace(/'/g, "'");
  44.     str = str.replace(/&/g, "&");
  45.     str = str.replace(/</g, "<");
  46.     str = str.replace(/>/g, ">");
  47.     return str;
  48. }

  49. function 采集AI回答列表(xml) {
  50.     var xmlStr = "" + xml;
  51.     var 回答列表 = [];

  52.     var messageLinearlayoutPattern = /<node[^>]*?resource-id="[^"]*?message_linearlayout"[^>]*?bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/g;
  53.     var lineMatch;
  54.    
  55.     while ((lineMatch = messageLinearlayoutPattern.exec(xmlStr)) !== null) {
  56.         var lineStart = lineMatch.index;
  57.         var lineEnd = xmlStr.indexOf('/node>', lineStart);
  58.         if (lineEnd === -1) lineEnd = xmlStr.length;
  59.         var lineContent = xmlStr.substring(lineStart, lineEnd);
  60.         
  61.         if (lineContent.indexOf('chats_message_dtmp_answer_container') !== -1) {
  62.             var textViewPattern = /<node[^>]*?text="([^"]+)"[^>]*?class="android\.widget\.TextView"[^>]*?\/?>/g;
  63.             var tvMatch;
  64.             while ((tvMatch = textViewPattern.exec(lineContent)) !== null) {
  65.                 if (tvMatch[1] && 字符串长度(tvMatch[1]) > 1) {
  66.                     var 原始文本 = tvMatch[1];
  67.                     var 解码文本 = 解码HTML实体(原始文本);
  68.                     if (!回答列表.includes(解码文本)) {
  69.                         回答列表.push(解码文本);
  70.                         print.log("✓ 在回答容器中找到文本: '" + 解码文本 + "'");
  71.                     }
  72.                 }
  73.             }
  74.         }
  75.     }
  76.    
  77.     if (回答列表.length === 0) {
  78.         print.log("⚠ 未找到AI回答节点");
  79.     } else {
  80.         print.log("✓ 采集到" + 回答列表.length + "条AI回答");
  81.     }

  82.     return 回答列表;
  83. }

  84. function 获取当前最后AI回答(xml) {
  85.     var 回答列表 = 采集AI回答列表(xml);
  86.     if (回答列表.length === 0) return "";
  87.     return 回答列表[回答列表.length - 1];
  88. }

  89. function 全屏截图(保存路径) {
  90.     try {
  91.         var result = agent.shell("screencap -p " + 保存路径);
  92.         print.log("✓ 截图命令执行:" + result);
  93.         
  94.         var lsResult = agent.shell("ls -la " + 保存路径);
  95.         print.log("✓ 截图文件检查:" + lsResult);
  96.         
  97.         return true;
  98.     } catch (e) {
  99.         print.log("⚠ 截图失败:" + e.message);
  100.         return false;
  101.     }
  102. }

  103. function 查找输入框中心(xml) {
  104.     var xmlStr = "" + xml;
  105.    
  106.     var inputIdx = xmlStr.indexOf('edConversationInput');
  107.     if (inputIdx === -1) {
  108.         inputIdx = xmlStr.indexOf('text="发消息或按住说话..."');
  109.     }
  110.     if (inputIdx === -1) {
  111.         inputIdx = xmlStr.indexOf('class="android.widget.EditText"');
  112.     }
  113.    
  114.     if (inputIdx !== -1) {
  115.         var 段 = xmlStr.substring(inputIdx);
  116.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  117.         if (m) {
  118.             var x1 = parseInt(m[1]);
  119.             var y1 = parseInt(m[2]);
  120.             var x2 = parseInt(m[3]);
  121.             var y2 = parseInt(m[4]);
  122.             print.log("✓ 输入框定位:bounds=[" + x1 + "," + y1 + "][" + x2 + "," + y2 + "]");
  123.             return {
  124.                 x: (x1 + x2) / 2,
  125.                 y: (y1 + y2) / 2
  126.             };
  127.         }
  128.     }

  129.     print.log("⚠ 未找到输入框,使用兜底坐标");
  130.     return {
  131.         x: 屏幕宽 * 0.4,
  132.         y: 屏幕高 * 0.92
  133.     };
  134. }

  135. function 查找加号按钮(xml) {
  136.     var xmlStr = "" + xml;
  137.    
  138.     var plusIdx = xmlStr.indexOf('flConversationInputPlus');
  139.     if (plusIdx !== -1) {
  140.         var 段 = xmlStr.substring(plusIdx);
  141.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  142.         if (m) {
  143.             var x = (parseInt(m[1]) + parseInt(m[3])) / 2;
  144.             var y = (parseInt(m[2]) + parseInt(m[4])) / 2;
  145.             print.log("✓ 加号按钮定位:flConversationInputPlus,坐标(" + Math.round(x) + "," + Math.round(y) + ")");
  146.             return { x: x, y: y };
  147.         }
  148.     }

  149.     var cvPlusIdx = xmlStr.indexOf('cv_chat_input_plus');
  150.     if (cvPlusIdx !== -1) {
  151.         var 段2 = xmlStr.substring(cvPlusIdx);
  152.         var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  153.         if (m2) {
  154.             var x = (parseInt(m2[1]) + parseInt(m2[3])) / 2;
  155.             var y = (parseInt(m2[2]) + parseInt(m2[4])) / 2;
  156.             print.log("✓ 加号按钮定位:cv_chat_input_plus,坐标(" + Math.round(x) + "," + Math.round(y) + ")");
  157.             return { x: x, y: y };
  158.         }
  159.     }

  160.     var 输入框 = 查找输入框中心(xml);
  161.     if (输入框) {
  162.         var 预估X = 屏幕宽 * 0.92;
  163.         var 预估Y = 输入框.y;
  164.         print.log("⚠ 未找到加号按钮,使用输入框右侧兜底坐标(" + Math.round(预估X) + "," + Math.round(预估Y) + ")");
  165.         return { x: 预估X, y: 预估Y };
  166.     }

  167.     print.log("⚠ 加号按钮使用屏幕右侧底部兜底坐标");
  168.     return {
  169.         x: 屏幕宽 * 0.92,
  170.         y: 屏幕高 * 0.92
  171.     };
  172. }

  173. function 粘贴文本(文本) {
  174.     try {
  175.         Clipboard.copy("" + 文本);
  176.     } catch (e) {
  177.         print.log("⚠ Clipboard.copy 失败:" + e.message);
  178.     }
  179.     sleep.millisecond(毫秒 = 300);

  180.     try {
  181.         agent.shell("service call clipboard 3 i32 1 s16 '" + 文本 + "' i32 0");
  182.     } catch (e2) {
  183.         // 忽略错误
  184.     }
  185.     sleep.millisecond(毫秒 = 300);

  186.     agent.shell("input keyevent 279");
  187.     sleep.second(秒 = 1);
  188.     print.log("✓ 已粘贴文本:" + 文本);
  189. }

  190. function 查找相册选项(xml) {
  191.     var xmlStr = "" + xml;
  192.    
  193.     var text关键词 = ["相册", "图片", "照片", "所有照片", "从相册选择", "选择图片"];
  194.     for (var i = 0; i < text关键词.length; i++) {
  195.         var kw = text关键词[i];
  196.         var idx = xmlStr.indexOf('text="' + kw + '"');
  197.         if (idx !== -1) {
  198.             var 段 = xmlStr.substring(idx);
  199.             var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  200.             if (m) {
  201.                 print.log("✓ 相册选项定位:text=" + kw);
  202.                 return {
  203.                     x: (parseInt(m[1]) + parseInt(m[3])) / 2,
  204.                     y: (parseInt(m[2]) + parseInt(m[4])) / 2
  205.                 };
  206.             }
  207.         }
  208.     }

  209.     var desc关键词 = ["相册", "图片", "照片"];
  210.     for (var j = 0; j < desc关键词.length; j++) {
  211.         var kw2 = desc关键词[j];
  212.         var idx2 = xmlStr.indexOf('content-desc="' + kw2 + '"');
  213.         if (idx2 !== -1) {
  214.             var 段2 = xmlStr.substring(idx2);
  215.             var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  216.             if (m2) {
  217.                 print.log("✓ 相册选项定位:content-desc=" + kw2);
  218.                 return {
  219.                     x: (parseInt(m2[1]) + parseInt(m2[3])) / 2,
  220.                     y: (parseInt(m2[2]) + parseInt(m2[4])) / 2
  221.                 };
  222.             }
  223.         }
  224.     }

  225.     return null;
  226. }

  227. function 是否在系统相册页面(xml) {
  228.     var xmlStr = "" + xml;
  229.    
  230.     var packageMatch = xmlStr.match(/package="([^"]+)"/);
  231.     var 当前包名 = packageMatch ? packageMatch[1] : "";
  232.     if (当前包名 && 当前包名 !== 元宝包名) {
  233.         print.log("✓ 检测到系统相册页面,包名:" + 当前包名);
  234.         return true;
  235.     }
  236.    
  237.     var gallery关键词 = ["最近", "图库", "Camera", "所有图片", "照片", "相册", "All photos", "Photos"];
  238.     for (var i = 0; i < gallery关键词.length; i++) {
  239.         if (xmlStr.indexOf('text="' + gallery关键词[i] + '"') !== -1 ||
  240.             xmlStr.indexOf('content-desc="' + gallery关键词[i] + '"') !== -1) {
  241.             var 有聊天输入 = xmlStr.indexOf("edConversationInput") !== -1;
  242.             if (!有聊天输入) {
  243.                 print.log("✓ 检测到相册页面(关键词:" + gallery关键词[i] + ")");
  244.                 return true;
  245.             }
  246.         }
  247.     }
  248.    
  249.     var 有图片文件 = xmlStr.indexOf('.png"') !== -1 || xmlStr.indexOf('.jpg"') !== -1 ||
  250.                      xmlStr.indexOf('.jpeg"') !== -1 || xmlStr.indexOf('.gif"') !== -1;
  251.     var 有选择按钮 = xmlStr.indexOf('text="选择"') !== -1;
  252.     var 有聊天输入2 = xmlStr.indexOf("edConversationInput") !== -1;
  253.     var 有聊天列表 = xmlStr.indexOf("chat_recycler_view") !== -1;
  254.    
  255.     if (有图片文件 && 有选择按钮 && !有聊天输入2 && !有聊天列表) {
  256.         print.log("✓ 检测到相册页面(元宝ComposeView,有图片文件和选择按钮)");
  257.         return true;
  258.     }
  259.    
  260.     return false;
  261. }

  262. function 是否在图片预览页面(xml) {
  263.     var xmlStr = "" + xml;
  264.     if (xmlStr.indexOf('text="完成"') !== -1 || xmlStr.indexOf('text="发送"') !== -1) {
  265.         return true;
  266.     }
  267.     if (xmlStr.indexOf('content-desc="完成"') !== -1 || xmlStr.indexOf('content-desc="发送"') !== -1) {
  268.         return true;
  269.     }
  270.     return false;
  271. }

  272. function 查找图片预览确认按钮(xml) {
  273.     var xmlStr = "" + xml;
  274.    
  275.     var 关键词 = ["完成", "发送", "确认"];
  276.     for (var i = 0; i < 关键词.length; i++) {
  277.         var kw = 关键词[i];
  278.         var textIdx = xmlStr.indexOf('text="' + kw + '"');
  279.         if (textIdx !== -1) {
  280.             var 段 = xmlStr.substring(textIdx);
  281.             var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  282.             if (m) {
  283.                 var x = (parseInt(m[1]) + parseInt(m[3])) / 2;
  284.                 var y = (parseInt(m[2]) + parseInt(m[4])) / 2;
  285.                 print.log("✓ 图片预览确认按钮定位:text=" + kw + ",坐标(" + Math.round(x) + "," + Math.round(y) + ")");
  286.                 return { x: x, y: y };
  287.             }
  288.         }
  289.     }
  290.    
  291.     for (var j = 0; j < 关键词.length; j++) {
  292.         var kw2 = 关键词[j];
  293.         var descIdx = xmlStr.indexOf('content-desc="' + kw2 + '"');
  294.         if (descIdx !== -1) {
  295.             var 段2 = xmlStr.substring(descIdx);
  296.             var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  297.             if (m2) {
  298.                 var x = (parseInt(m2[1]) + parseInt(m2[3])) / 2;
  299.                 var y = (parseInt(m2[2]) + parseInt(m2[4])) / 2;
  300.                 print.log("✓ 图片预览确认按钮定位:content-desc=" + kw2 + ",坐标(" + Math.round(x) + "," + Math.round(y) + ")");
  301.                 return { x: x, y: y };
  302.             }
  303.         }
  304.     }
  305.    
  306.     print.log("⚠ 图片预览确认按钮使用兜底坐标(底部中间)");
  307.     return { x: 屏幕宽 * 0.5, y: 屏幕高 * 0.92 };
  308. }

  309. function 查找相册选择按钮(xml) {
  310.     var xmlStr = "" + xml;
  311.    
  312.     var 关键词列表 = ["选择", "完成", "确认", "发送", "确定"];
  313.     for (var i = 0; i < 关键词列表.length; i++) {
  314.         var kw = 关键词列表[i];
  315.         
  316.         var textPattern = new RegExp('text="' + kw + '[^"]*"[^>]*?bounds="\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]"', 'gi');
  317.         var textMatch = textPattern.exec(xmlStr);
  318.         if (textMatch) {
  319.             var x = (parseInt(textMatch[1]) + parseInt(textMatch[3])) / 2;
  320.             var y = (parseInt(textMatch[2]) + parseInt(textMatch[4])) / 2;
  321.             print.log("✓ 相册选择按钮定位:text=" + kw + ",坐标(" + Math.round(x) + "," + Math.round(y) + ")");
  322.             return { x: x, y: y };
  323.         }
  324.         
  325.         var descIdx = xmlStr.indexOf('content-desc="' + kw + '"');
  326.         if (descIdx !== -1) {
  327.             var 段2 = xmlStr.substring(descIdx);
  328.             var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  329.             if (m2) {
  330.                 var x = (parseInt(m2[1]) + parseInt(m2[3])) / 2;
  331.                 var y = (parseInt(m2[2]) + parseInt(m2[4])) / 2;
  332.                 print.log("✓ 相册选择按钮定位:content-desc=" + kw + ",坐标(" + Math.round(x) + "," + Math.round(y) + ")");
  333.                 return { x: x, y: y };
  334.             }
  335.         }
  336.     }
  337.    
  338.     var bottomButtonPattern = /<node[^>]*?clickable="true"[^>]*?bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/g;
  339.     var bottomMatch;
  340.     var 底部按钮列表 = [];
  341.     while ((bottomMatch = bottomButtonPattern.exec(xmlStr)) !== null) {
  342.         var bx1 = parseInt(bottomMatch[1]);
  343.         var by1 = parseInt(bottomMatch[2]);
  344.         var bx2 = parseInt(bottomMatch[3]);
  345.         var by2 = parseInt(bottomMatch[4]);
  346.         if (by1 >= 屏幕高 * 0.85) {
  347.             底部按钮列表.push({ x: (bx1 + bx2) / 2, y: (by1 + by2) / 2 });
  348.         }
  349.     }
  350.    
  351.     if (底部按钮列表.length > 0) {
  352.         底部按钮列表.sort(function(a, b) { return b.x - a.x; });
  353.         var 最右边按钮 = 底部按钮列表[0];
  354.         print.log("✓ 相册选择按钮定位:底部最右边按钮,坐标(" + Math.round(最右边按钮.x) + "," + Math.round(最右边按钮.y) + ")");
  355.         return { x: 最右边按钮.x, y: 最右边按钮.y };
  356.     }
  357.    
  358.     print.log("⚠ 相册选择按钮使用兜底坐标(底部)");
  359.     return { x: 屏幕宽 * 0.78, y: 屏幕高 * 0.92 };
  360. }

  361. function 查找第一张图片(xml) {
  362.     var xmlStr = "" + xml;
  363.    
  364.     if (是否在系统相册页面(xmlStr)) {
  365.         agent.shell("echo '" + xmlStr.substring(0, 5000) + "' > /sdcard/相册UI_dump.xml");
  366.         print.log("✓ 已保存相册UI XML到/sdcard/相册UI_dump.xml");
  367.         
  368.         var nafPattern = /<node[^>]*?NAF="true"[^>]*?clickable="true"[^>]*?bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/g;
  369.         var nafMatch;
  370.         var NAF小圆点列表 = [];
  371.         
  372.         while ((nafMatch = nafPattern.exec(xmlStr)) !== null) {
  373.             var nx1 = parseInt(nafMatch[1]);
  374.             var ny1 = parseInt(nafMatch[2]);
  375.             var nx2 = parseInt(nafMatch[3]);
  376.             var ny2 = parseInt(nafMatch[4]);
  377.             var nw = nx2 - nx1;
  378.             var nh = ny2 - ny1;
  379.             
  380.             if (nw >= 50 && nw <= 300 && nh >= 50 && nh <= 300) {
  381.                 if (ny1 >= 400 && ny2 <= 屏幕高 - 400) {
  382.                     NAF小圆点列表.push({ x1: nx1, y1: ny1, x2: nx2, y2: ny2, x: (nx1 + nx2) / 2, y: (ny1 + ny2) / 2 });
  383.                 }
  384.             }
  385.         }
  386.         
  387.         if (NAF小圆点列表.length > 0) {
  388.             NAF小圆点列表.sort(function(a, b) {
  389.                 if (a.y1 !== b.y1) return a.y1 - b.y1;
  390.                 return a.x1 - b.x1;
  391.             });
  392.             var 选中小圆点 = NAF小圆点列表[0];
  393.             print.log("✓ ComposeView找到NAF小圆点选择框:坐标(" + Math.round(选中小圆点.x) + "," + Math.round(选中小圆点.y) + "),bounds=[" + 选中小圆点.x1 + "," + 选中小圆点.y1 + "][" + 选中小圆点.x2 + "," + 选中小圆点.y2 + "]");
  394.             return { x: 选中小圆点.x, y: 选中小圆点.y };
  395.         }
  396.         
  397.         var imageDescPattern = /<node[^>]*?content-desc="([^"]+\.(png|jpg|jpeg|gif))"[^>]*?class="android\.view\.View"[^>]*?bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/gi;
  398.         var imgMatch;
  399.         var 图片节点列表 = [];
  400.         
  401.         while ((imgMatch = imageDescPattern.exec(xmlStr)) !== null) {
  402.             var 文件名 = imgMatch[1];
  403.             var ix1 = parseInt(imgMatch[3]);
  404.             var iy1 = parseInt(imgMatch[4]);
  405.             var ix2 = parseInt(imgMatch[5]);
  406.             var iy2 = parseInt(imgMatch[6]);
  407.             var iw = ix2 - ix1;
  408.             var ih = iy2 - iy1;
  409.             
  410.             if (iw >= 100 && ih >= 100) {
  411.                 图片节点列表.push({ 文件名: 文件名, x1: ix1, y1: iy1, x2: ix2, y2: iy2, w: iw, h: ih });
  412.             }
  413.         }
  414.         
  415.         if (图片节点列表.length > 0) {
  416.             图片节点列表.sort(function(a, b) {
  417.                 if (a.y1 !== b.y1) return a.y1 - b.y1;
  418.                 return a.x1 - b.x1;
  419.             });
  420.             var 第一张图片 = 图片节点列表[0];
  421.             print.log("✓ 找到图片:" + 第一张图片.文件名 + ",bounds=[" + 第一张图片.x1 + "," + 第一张图片.y1 + "][" + 第一张图片.x2 + "," + 第一张图片.y2 + "]");
  422.             
  423.             var 选择框X = 第一张图片.x1 + 第一张图片.w * 0.77;
  424.             var 选择框Y = 第一张图片.y1 + 第一张图片.h * 0.24;
  425.             print.log("✓ 计算小圆点选择框坐标:(" + Math.round(选择框X) + "," + Math.round(选择框Y) + ")");
  426.             return { x: 选择框X, y: 选择框Y };
  427.         }
  428.         
  429.         var clickableViewPattern = /<node[^>]*?clickable="true"[^>]*?bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/g;
  430.         var clickMatch;
  431.         var 可点击区域 = [];
  432.         while ((clickMatch = clickableViewPattern.exec(xmlStr)) !== null) {
  433.             var cx1 = parseInt(clickMatch[1]);
  434.             var cy1 = parseInt(clickMatch[2]);
  435.             var cx2 = parseInt(clickMatch[3]);
  436.             var cy2 = parseInt(clickMatch[4]);
  437.             var cw = cx2 - cx1;
  438.             var ch = cy2 - cy1;
  439.             可点击区域.push({ x1: cx1, y1: cy1, x2: cx2, y2: cy2, w: cw, h: ch, x: (cx1 + cx2) / 2, y: (cy1 + cy2) / 2 });
  440.         }
  441.         
  442.         var 图片区域内可点击 = [];
  443.         for (var k = 0; k < 可点击区域.length; k++) {
  444.             var item = 可点击区域[k];
  445.             if (item.y >= 400 && item.y <= 屏幕高 - 400) {
  446.                 图片区域内可点击.push(item);
  447.             }
  448.         }
  449.         
  450.         if (图片区域内可点击.length > 0) {
  451.             图片区域内可点击.sort(function(a, b) {
  452.                 if (a.y !== b.y) return a.y - b.y;
  453.                 return a.x - b.x;
  454.             });
  455.             var 第一个可点击 = 图片区域内可点击[0];
  456.             print.log("✓ ComposeView图片区域内第一个可点击元素:坐标(" + Math.round(第一个可点击.x) + "," + Math.round(第一个可点击.y) + ")");
  457.             return { x: 第一个可点击.x, y: 第一个可点击.y };
  458.         }

  459.         print.log("⚠ 系统相册未找到图片,输出调试信息:");
  460.         print.log("  当前包名:" + xmlStr.match(/package="([^"]+)"/)[1]);
  461.         print.log("  XML前1000字符:" + xmlStr.substring(0, 1000));
  462.         print.log("  NAF小圆点数量:" + NAF小圆点列表.length);
  463.         print.log("  图片节点数量:" + 图片节点列表.length);
  464.         
  465.         var allImgViews = xmlStr.match(/class="android\.widget\.ImageView"/g);
  466.         print.log("  全部ImageView数量:" + (allImgViews ? allImgViews.length : 0));
  467.         
  468.         return { x: 屏幕宽 * 0.25, y: 屏幕高 * 0.3 };
  469.     }

  470.     var rvPattern = /<node[^>]*?class="androidx\.recyclerview\.widget\.RecyclerView"[^>]*?bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/g;
  471.     var rvMatch;
  472.     var 图片列表区域 = null;

  473.     while ((rvMatch = rvPattern.exec(xmlStr)) !== null) {
  474.         var rx1 = parseInt(rvMatch[1]);
  475.         var ry1 = parseInt(rvMatch[2]);
  476.         var rx2 = parseInt(rvMatch[3]);
  477.         var ry2 = parseInt(rvMatch[4]);
  478.         var 高度 = ry2 - ry1;

  479.         if (ry1 > 屏幕高 * 0.7 && 高度 > 300) {
  480.             图片列表区域 = {x1: rx1, y1: ry1, x2: rx2, y2: ry2};
  481.             print.log("✓ 找到底部图片列表RecyclerView:[" + rx1 + "," + ry1 + "][" + rx2 + "," + ry2 + "]");
  482.             break;
  483.         }
  484.     }

  485.     if (图片列表区域) {
  486.         var imgPattern = /<node[^>]*?class="android\.widget\.ImageView"[^>]*?\/?>/g;
  487.         var imgMatch;
  488.         var 候选 = [];
  489.         while ((imgMatch = imgPattern.exec(xmlStr)) !== null) {
  490.             var imgNode = imgMatch[0];
  491.             var boundsMatch = imgNode.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  492.             if (!boundsMatch) continue;
  493.             var ix1 = parseInt(boundsMatch[1]);
  494.             var iy1 = parseInt(boundsMatch[2]);
  495.             var ix2 = parseInt(boundsMatch[3]);
  496.             var iy2 = parseInt(boundsMatch[4]);
  497.             var iw = ix2 - ix1;
  498.             var ih = iy2 - iy1;

  499.             var 在区域内 = (ix1 >= 图片列表区域.x1 && ix2 <= 图片列表区域.x2 &&
  500.                             iy1 >= 图片列表区域.y1 && iy2 <= 图片列表区域.y2);
  501.             var 是大图 = (iw > 100 && ih > 100);

  502.             if (在区域内 && 是大图) {
  503.                 候选.push({
  504.                     x: (ix1 + ix2) / 2,
  505.                     y: (iy1 + iy2) / 2,
  506.                     y1: iy1,
  507.                     x1: ix1
  508.                 });
  509.             }
  510.         }

  511.         if (候选.length > 0) {
  512.             候选.sort(function(a, b) {
  513.                 if (a.y1 !== b.y1) return a.y1 - b.y1;
  514.                 return a.x1 - b.x1;
  515.             });
  516.             var 选中 = 候选[0];
  517.             print.log("✓ 第一张图片定位:底部图片列表内的ImageView,坐标(" + Math.round(选中.x) + "," + Math.round(选中.y) + ")");
  518.             return { x: 选中.x, y: 选中.y };
  519.         }
  520.     }

  521.     var imgPattern2 = /<node[^>]*?class="android\.widget\.ImageView"[^>]*?\/?>/g;
  522.     var imgMatch2;
  523.     var 候选2 = [];
  524.     while ((imgMatch2 = imgPattern2.exec(xmlStr)) !== null) {
  525.         var imgNode = imgMatch2[0];
  526.         var boundsMatch = imgNode.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  527.         if (!boundsMatch) continue;
  528.         var ix1 = parseInt(boundsMatch[1]);
  529.         var iy1 = parseInt(boundsMatch[2]);
  530.         var ix2 = parseInt(boundsMatch[3]);
  531.         var iy2 = parseInt(boundsMatch[4]);
  532.         var iw = ix2 - ix1;
  533.         var ih = iy2 - iy1;

  534.         if (iy1 > 屏幕高 * 0.7 && iw > 100 && ih > 100) {
  535.             候选2.push({
  536.                 x: (ix1 + ix2) / 2,
  537.                 y: (iy1 + iy2) / 2,
  538.                 y1: iy1,
  539.                 x1: ix1
  540.             });
  541.         }
  542.     }

  543.     if (候选2.length > 0) {
  544.         候选2.sort(function(a, b) {
  545.             if (a.y1 !== b.y1) return a.y1 - b.y1;
  546.             return a.x1 - b.x1;
  547.         });
  548.         var 选中2 = 候选2[0];
  549.         print.log("✓ 第一张图片定位:底部区域ImageView,坐标(" + Math.round(选中2.x) + "," + Math.round(选中2.y) + ")");
  550.         return { x: 选中2.x, y: 选中2.y };
  551.     }

  552.     print.log("⚠ 未找到图片,使用兜底坐标(底部第一行第一列)");
  553.     return { x: 屏幕宽 * 0.15, y: 屏幕高 * 0.85 };
  554. }

  555. function 查找发送按钮中心(xml) {
  556.     var xmlStr = "" + xml;

  557.     var sendTextIdx = xmlStr.indexOf('text="发送"');
  558.     if (sendTextIdx !== -1) {
  559.         var 段 = xmlStr.substring(sendTextIdx);
  560.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  561.         if (m) {
  562.             print.log("✓ 发送按钮定位:文本匹配");
  563.             return {
  564.                 x: (parseInt(m[1]) + parseInt(m[3])) / 2,
  565.                 y: (parseInt(m[2]) + parseInt(m[4])) / 2
  566.             };
  567.         }
  568.     }

  569.     var inputIdx = xmlStr.indexOf('edConversationInput');
  570.     if (inputIdx !== -1) {
  571.         var 输入框段 = xmlStr.substring(inputIdx);
  572.         var 输入框边界 = 输入框段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  573.         if (输入框边界) {
  574.             var 输入框信息 = {
  575.                 x1: parseInt(输入框边界[1]),
  576.                 y1: parseInt(输入框边界[2]),
  577.                 x2: parseInt(输入框边界[3]),
  578.                 y2: parseInt(输入框边界[4]),
  579.                 centerY: (parseInt(输入框边界[2]) + parseInt(输入框边界[4])) / 2
  580.             };

  581.             var clickablePattern = /<node[^>]*?clickable="true"[^>]*?bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"[^>]*?\/?>/g;
  582.             var clickMatch;
  583.             var candidates = [];

  584.             while ((clickMatch = clickablePattern.exec(xmlStr)) !== null) {
  585.                 var cx1 = parseInt(clickMatch[1]);
  586.                 var cy1 = parseInt(clickMatch[2]);
  587.                 var cx2 = parseInt(clickMatch[3]);
  588.                 var cy2 = parseInt(clickMatch[4]);
  589.                 var cw = cx2 - cx1;
  590.                 var ch = cy2 - cy1;

  591.                 var 是小按钮 = (cw < 300 && ch < 300);
  592.                 var 在输入框右侧 = (cx1 > 输入框信息.x2 - 100);
  593.                 var 在输入框水平行 = (cy1 >= 输入框信息.y1 - 100 && cy1 <= 输入框信息.y2 + 100);

  594.                 if (是小按钮 && 在输入框右侧 && 在输入框水平行) {
  595.                     candidates.push({
  596.                         x1: cx1, y1: cy1, x2: cx2, y2: cy2,
  597.                         x: (cx1 + cx2) / 2,
  598.                         y: (cy1 + cy2) / 2
  599.                     });
  600.                 }
  601.             }

  602.             if (candidates.length > 0) {
  603.                 var 发送按钮候选 = [];
  604.                 for (var ci = 0; ci < candidates.length; ci++) {
  605.                     var cand = candidates[ci];
  606.                     if (cand.y1 >= 输入框信息.y1 + 300) {
  607.                         发送按钮候选.push(cand);
  608.                     }
  609.                 }
  610.                
  611.                 if (发送按钮候选.length > 0) {
  612.                     发送按钮候选.sort(function(a, b) {
  613.                         return b.x1 - a.x1;
  614.                     });
  615.                     var 选中 = 发送按钮候选[0];
  616.                     print.log("✓ 发送按钮定位:输入框右侧下方clickable元素,坐标(" + Math.round(选中.x) + "," + Math.round(选中.y) + ")");
  617.                     return { x: 选中.x, y: 选中.y };
  618.                 }
  619.                
  620.                 candidates.sort(function(a, b) {
  621.                     return b.x1 - a.x1;
  622.                 });
  623.                 var 选中 = candidates[0];
  624.                 print.log("✓ 发送按钮定位:输入框右侧clickable元素,坐标(" + Math.round(选中.x) + "," + Math.round(选中.y) + ")");
  625.                 return { x: 选中.x, y: 选中.y };
  626.             }

  627.             var 预估X = 输入框信息.x2 + 100;
  628.             var 预估Y = 输入框信息.centerY;
  629.             print.log("⚠ 发送按钮使用输入框右侧兜底坐标(" + Math.round(预估X) + "," + Math.round(预估Y) + ")");
  630.             return { x: 预估X, y: 预估Y };
  631.         }
  632.     }

  633.     print.log("⚠ 发送按钮使用屏幕右侧兜底策略");
  634.     return {
  635.         x: 屏幕宽 * 0.92,
  636.         y: 屏幕高 * 0.92
  637.     };
  638. }

  639. function 等待AI回答完成(发送前的最后文本, 发送前回答数量) {
  640.     var 已耗时 = 0;
  641.     var 检查间隔秒 = 1;

  642.     print.log("发送前最后AI回答:'" + 发送前的最后文本 + "',发送前回答数量:" + 发送前回答数量);

  643.     while (已耗时 < 等待回答超时秒) {
  644.         sleep.second(秒 = 检查间隔秒);
  645.         已耗时 += 检查间隔秒;

  646.         xml = 获取UI();
  647.         var 回答列表 = 采集AI回答列表(xml);
  648.         
  649.         if (回答列表.length > 0) {
  650.             var 当前最后回答 = 回答列表[回答列表.length - 1];
  651.             
  652.             var 有新回答 = (当前最后回答 !== 发送前的最后文本);
  653.             var 回答数量增加 = (回答列表.length > 发送前回答数量);
  654.             
  655.             if (有新回答 || 回答数量增加) {
  656.                 print.log("✓ 检测到新回答(" + 已耗时 + "秒):'" + 当前最后回答 + "',数量:" + 回答列表.length);
  657.                
  658.                 var 等待完成 = 0;
  659.                 var 上次长度 = 字符串长度(当前最后回答);
  660.                 while (等待完成 < 回答输出等待秒) {
  661.                     sleep.second(秒 = 1);
  662.                     等待完成++;
  663.                     
  664.                     xml = 获取UI();
  665.                     var 当前列表 = 采集AI回答列表(xml);
  666.                     if (当前列表.length > 0) {
  667.                         var 当前文本 = 当前列表[当前列表.length - 1];
  668.                         if (字符串长度(当前文本) === 上次长度) {
  669.                             print.log("✓ 文本停止变化,返回采集结果:" + 当前文本);
  670.                             return 当前文本;
  671.                         }
  672.                         上次长度 = 字符串长度(当前文本);
  673.                     }
  674.                 }
  675.                
  676.                 var 最终列表 = 采集AI回答列表(xml);
  677.                 if (最终列表.length > 0) {
  678.                     var 最终文本 = 最终列表[最终列表.length - 1];
  679.                     print.log("✓ 采集成功,返回结果:" + 最终文本);
  680.                     return 最终文本;
  681.                 }
  682.             }
  683.         }
  684.     }

  685.     print.log("⚠ 等待AI回答超时(" + 等待回答超时秒 + "秒),尝试返回当前内容");
  686.     xml = 获取UI();
  687.     var 兜底列表 = 采集AI回答列表(xml);
  688.     if (兜底列表.length > 0) {
  689.         var 兜底文本 = 兜底列表[兜底列表.length - 1];
  690.         print.log("✓ 超时兜底:返回当前采集到的回答:" + 兜底文本);
  691.         return 兜底文本;
  692.     }
  693.     return null;
  694. }

  695. // ========== 主流程开始 ==========

  696. function 主流程() {
  697.     // 步骤1:全屏截图(B站验证码页面)
  698.     print.log("\n========== 步骤1:全屏截图B站验证码 ==========");
  699.     var 截图成功 = 全屏截图(截图保存路径);
  700.     if (!截图成功) {
  701.         print.log("✗ 截图失败,退出流程");
  702.         print.log("===== 元宝识别验证码拖动B站流程结束 =====");
  703.         return;
  704.     }

  705.     // 步骤2:启动元宝APP
  706.     print.log("\n========== 步骤2:启动元宝APP ==========");
  707.     try {
  708.         app.openApp(元宝包名);
  709.         print.log("✓ 已启动元宝");
  710.     } catch (e) {
  711.         print.log("⚠ 启动失败:" + e.message);
  712.     }
  713.     sleep.second(秒 = 5);

  714.     // 步骤3:确认进入对话页面
  715.     print.log("\n========== 步骤3:确认进入对话页面 ==========");
  716.     var xml = 获取UI();
  717.     var hasRecyclerView = (xml.indexOf("chat_recycler_view") !== -1);
  718.     if (!hasRecyclerView) {
  719.         print.log("⚠ 当前页面可能不是元宝对话页,再次等待");
  720.         sleep.second(秒 = 3);
  721.         xml = 获取UI();
  722.         hasRecyclerView = (xml.indexOf("chat_recycler_view") !== -1);
  723.     }

  724.     if (hasRecyclerView) {
  725.         print.log("✓ 已进入元宝对话页面");
  726.     } else {
  727.         print.log("⚠ 未检测到消息列表,继续尝试");
  728.     }

  729.     // 步骤4:记录发送前的最后一条AI回答和数量
  730.     var 发送前回答列表 = 采集AI回答列表(xml);
  731.     var 发送前回答数量 = 发送前回答列表.length;
  732.     var 发送前最后文本 = "";
  733.     if (发送前回答列表.length > 0) {
  734.         发送前最后文本 = 发送前回答列表[发送前回答列表.length - 1];
  735.     }
  736.     print.log("✓ 发送前回答数量:" + 发送前回答数量 + ",最后文本:'" + 发送前最后文本 + "'");

  737.     // 步骤5:点击加号按钮打开附件菜单
  738.     print.log("\n========== 步骤5:点击加号按钮打开附件菜单 ==========");
  739.     var 加号按钮 = 查找加号按钮(xml);
  740.     agent.click(加号按钮.x, 加号按钮.y);
  741.     print.log("✓ 已点击加号按钮,坐标(" + Math.round(加号按钮.x) + "," + Math.round(加号按钮.y) + ")");
  742.     sleep.second(秒 = 2);

  743.     // 步骤6:选择相册或图片
  744.     print.log("\n========== 步骤6:选择相册或图片 ==========");
  745.     var 相册选择成功 = false;
  746.     var 尝试次数 = 0;
  747.     while (!相册选择成功 && 尝试次数 < 5) {
  748.         尝试次数++;
  749.         xml = 获取UI();
  750.         
  751.         if (是否在系统相册页面(xml)) {
  752.             print.log("✓ 已进入系统相册页面");
  753.             相册选择成功 = true;
  754.             break;
  755.         }
  756.         
  757.         var 相册选项 = 查找相册选项(xml);
  758.         if (相册选项) {
  759.             agent.click(相册选项.x, 相册选项.y);
  760.             print.log("✓ 已点击相册选项,坐标(" + Math.round(相册选项.x) + "," + Math.round(相册选项.y) + ")");
  761.             sleep.second(秒 = 2);
  762.             相册选择成功 = true;
  763.             break;
  764.         }
  765.         
  766.         var imgCount = (xml.match(/class="android\.widget\.ImageView"/g) || []).length;
  767.         if (imgCount >= 4) {
  768.             print.log("✓ 加号菜单底部已显示图片列表(检测到" + imgCount + "个图片)");
  769.             相册选择成功 = true;
  770.             break;
  771.         }
  772.         
  773.         print.log("⚠ 第" + 尝试次数 + "次尝试:未找到相册选项,等待重试");
  774.         sleep.second(秒 = 1);
  775.     }

  776.     // 步骤7:选择第一张图片(处理系统相册和图片预览页面)
  777.     print.log("\n========== 步骤7:选择第一张图片 ==========");
  778.     var 图片选择成功 = false;
  779.     var 图片尝试次数 = 0;
  780.     while (!图片选择成功 && 图片尝试次数 < 10) {
  781.         图片尝试次数++;
  782.         xml = 获取UI();
  783.         
  784.         if (图片尝试次数 === 1) {
  785.             var pkgMatch = xml.match(/package="([^"]+)"/);
  786.             print.log("调试:当前包名=" + (pkgMatch ? pkgMatch[1] : "未知"));
  787.             print.log("调试:XML前300字符=" + xml.substring(0, 300));
  788.             print.log("调试:是否有edConversationInput=" + (xml.indexOf("edConversationInput") !== -1));
  789.             print.log("调试:是否有chat_recycler_view=" + (xml.indexOf("chat_recycler_view") !== -1));
  790.             var dbgImgCount = (xml.match(/class="android\.widget\.ImageView"/g) || []).length;
  791.             print.log("调试:ImageView数量=" + dbgImgCount);
  792.         }
  793.         
  794.         if (是否在图片预览页面(xml)) {
  795.             var 确认按钮 = 查找图片预览确认按钮(xml);
  796.             agent.click(确认按钮.x, 确认按钮.y);
  797.             print.log("✓ 已点击图片预览确认按钮,坐标(" + Math.round(确认按钮.x) + "," + Math.round(确认按钮.y) + ")");
  798.             图片选择成功 = true;
  799.             sleep.second(秒 = 3);
  800.             break;
  801.         }
  802.         
  803.         if (是否在系统相册页面(xml)) {
  804.             var 第一张图片 = 查找第一张图片(xml);
  805.             if (第一张图片) {
  806.                 agent.click(第一张图片.x, 第一张图片.y);
  807.                 print.log("✓ 已点击第一张图片右上角小圆点,坐标(" + Math.round(第一张图片.x) + "," + Math.round(第一张图片.y) + ")");
  808.                 sleep.second(秒 = 2);
  809.                
  810.                 xml = 获取UI();
  811.                 var 选择按钮 = 查找相册选择按钮(xml);
  812.                 if (选择按钮) {
  813.                     agent.click(选择按钮.x, 选择按钮.y);
  814.                     print.log("✓ 已点击选择按钮,坐标(" + Math.round(选择按钮.x) + "," + Math.round(选择按钮.y) + ")");
  815.                     图片选择成功 = true;
  816.                     sleep.second(秒 = 3);
  817.                     break;
  818.                 } else {
  819.                     print.log("⚠ 第" + 图片尝试次数 + "次:未找到选择按钮,重新获取XML重试");
  820.                     sleep.second(秒 = 1);
  821.                     continue;
  822.                 }
  823.             } else {
  824.                 print.log("⚠ 系统相册未找到图片");
  825.                 sleep.second(秒 = 1);
  826.                 continue;
  827.             }
  828.         }
  829.         
  830.         print.log("⚠ 第" + 图片尝试次数 + "次尝试:未检测到相册页面,等待重试");
  831.         sleep.second(秒 = 1);
  832.     }

  833.     // 步骤8:等待图片添加到输入区域(等待回到元宝对话页面)
  834.     print.log("\n========== 步骤8:等待图片添加到输入区域 ==========");
  835.     var 图片添加成功 = false;
  836.     var 等待尝试次数 = 0;
  837.     while (!图片添加成功 && 等待尝试次数 < 10) {
  838.         等待尝试次数++;
  839.         xml = 获取UI();
  840.         
  841.         var packageMatch = xml.match(/package="([^"]+)"/);
  842.         if (packageMatch && packageMatch[1] === 元宝包名) {
  843.             print.log("✓ 已回到元宝对话页面");
  844.             if (xml.indexOf("edConversationInput") !== -1) {
  845.                 print.log("✓ 图片已添加到输入区域");
  846.                 图片添加成功 = true;
  847.                 break;
  848.             }
  849.         }
  850.         
  851.         print.log("⚠ 第" + 等待尝试次数 + "次尝试:图片尚未添加,等待重试");
  852.         sleep.second(秒 = 1);
  853.     }
  854.    
  855.     if (!图片添加成功) {
  856.         print.log("⚠ 多次等待图片未添加,继续后续步骤");
  857.     }

  858.     // 步骤9:粘贴文字询问拖动距离
  859.     print.log("\n========== 步骤9:粘贴文字询问拖动距离 ==========");
  860.     xml = 获取UI();
  861.     var 输入框 = 查找输入框中心(xml);
  862.     var AI回答 = null;
  863.     if (输入框) {
  864.         agent.click(输入框.x, 输入框.y);
  865.         sleep.second(秒 = 1);
  866.         粘贴文本(提问话术);
  867.         print.log("✓ 已粘贴文本:" + 提问话术);
  868.         sleep.second(秒 = 2);

  869.         // 步骤10:发送图片和文字
  870.         print.log("\n========== 步骤10:发送图片和文字 ==========");
  871.         xml = 获取UI();
  872.         var 发送按钮 = 查找发送按钮中心(xml);
  873.         if (发送按钮) {
  874.             agent.click(发送按钮.x, 发送按钮.y);
  875.             print.log("✓ 已点击发送按钮,坐标(" + Math.round(发送按钮.x) + "," + Math.round(发送按钮.y) + ")");
  876.         } else {
  877.             agent.shell("input keyevent 66");
  878.             print.log("⚠ 未找到发送按钮,已尝试按回车发送");
  879.         }
  880.         sleep.second(秒 = 3);

  881.         // 步骤11:等待元宝AI回答
  882.         print.log("\n========== 步骤11:等待元宝AI回答 ==========");
  883.         AI回答 = 等待AI回答完成(发送前最后文本, 发送前回答数量);
  884.     } else {
  885.         print.log("⚠ 未找到输入框");
  886.     }
  887.    
  888.     if (!AI回答) {
  889.         print.log("✗ 未获取到AI回答");
  890.         print.log("===== 元宝识别验证码拖动B站流程结束 =====");
  891.         return;
  892.     }

  893.     print.log("\n✓ 采集到AI回答");
  894.     print.log("--- 采集内容开始 ---");
  895.     print.log(AI回答);
  896.     print.log("--- 采集内容结束 ---");

  897.     // 步骤12:解析拖动距离坐标
  898.     print.log("\n========== 步骤12:解析拖动距离坐标 ==========");
  899.     print.log("✓ AI原始回答:'" + AI回答 + "'");
  900.    
  901.     var 所有数字 = AI回答.match(/\d+/g);
  902.     var 拖动距离像素 = null;
  903.     var AI图像宽度 = null;
  904.    
  905.     if (所有数字 && 所有数字.length >= 2) {
  906.         var 数字列表 = [];
  907.         for (var i = 0; i < 所有数字.length; i++) {
  908.             数字列表.push(parseInt(所有数字[i]));
  909.         }
  910.         print.log("✓ 提取到所有数字:" + 数字列表.join(", "));
  911.         
  912.         if (数字列表.length >= 5) {
  913.             var x1 = 数字列表[0];
  914.             var y1 = 数字列表[1];
  915.             var x2 = 数字列表[2];
  916.             var y2 = 数字列表[3];
  917.             AI图像宽度 = 数字列表[4];
  918.             拖动距离像素 = Math.abs(x2 - x1);
  919.             print.log("✓ 识别到两组坐标+图像宽度:(" + x1 + "," + y1 + ") 和 (" + x2 + "," + y2 + "),图像宽度=" + AI图像宽度);
  920.             print.log("✓ 计算拖动距离:|x2 - x1| = |" + x2 + " - " + x1 + "| = " + 拖动距离像素);
  921.         } else if (数字列表.length >= 4) {
  922.             var x1 = 数字列表[0];
  923.             var y1 = 数字列表[1];
  924.             var x2 = 数字列表[2];
  925.             var y2 = 数字列表[3];
  926.             拖动距离像素 = Math.abs(x2 - x1);
  927.             AI图像宽度 = Math.max(x1, x2) + 100;
  928.             print.log("✓ 识别到两组坐标格式:(" + x1 + "," + y1 + ") 和 (" + x2 + "," + y2 + ")");
  929.             print.log("✓ 计算拖动距离:|x2 - x1| = |" + x2 + " - " + x1 + "| = " + 拖动距离像素);
  930.             print.log("✓ 估算图像宽度:max(x1,x2)+100 = " + AI图像宽度);
  931.         } else if (数字列表.length >= 2) {
  932.             var 坐标匹配 = AI回答.match(/(\d+)\s*[,,]\s*(\d+)/);
  933.             if (坐标匹配) {
  934.                 var cx1 = parseInt(坐标匹配[1]);
  935.                 var cx2 = parseInt(坐标匹配[2]);
  936.                 拖动距离像素 = Math.abs(cx2 - cx1);
  937.                 AI图像宽度 = Math.max(cx1, cx2) + 100;
  938.                 print.log("✓ 识别到坐标格式:(" + cx1 + "," + cx2 + "),计算距离:" + 拖动距离像素);
  939.             } else {
  940.                 拖动距离像素 = 数字列表[0];
  941.                 print.log("✓ 提取到单个数字(拖动距离):" + 拖动距离像素);
  942.             }
  943.         } else {
  944.             拖动距离像素 = 数字列表[0];
  945.             print.log("✓ 提取到单个数字(拖动距离):" + 拖动距离像素);
  946.         }
  947.     } else if (所有数字 && 所有数字.length === 1) {
  948.         拖动距离像素 = parseInt(所有数字[0]);
  949.         print.log("✓ 提取到单个数字(拖动距离):" + 拖动距离像素);
  950.     } else {
  951.         print.log("✗ 未找到有效的拖动距离");
  952.         print.log("===== 元宝识别验证码拖动B站流程结束 =====");
  953.         return;
  954.     }
  955.    
  956.     var 图像缩放系数 = 1.0;
  957.     if (AI图像宽度 && AI图像宽度 > 0 && AI图像宽度 < 屏幕宽) {
  958.         图像缩放系数 = 屏幕宽 / AI图像宽度;
  959.         if (图像缩放系数 > 5) {
  960.             图像缩放系数 = 1.0;
  961.         } else {
  962.             拖动距离像素 = Math.round(拖动距离像素 * 图像缩放系数);
  963.             print.log("✓ 图像缩放补偿:AI图像宽度=" + AI图像宽度 + ",屏幕宽=" + 屏幕宽);
  964.             print.log("✓ 缩放系数=" + 图像缩放系数.toFixed(2) + ",补偿后拖动距离=" + 拖动距离像素);
  965.         }
  966.     } else if (拖动距离像素 < 200) {
  967.         图像缩放系数 = 屏幕宽 / 750;
  968.         拖动距离像素 = Math.round(拖动距离像素 * 图像缩放系数);
  969.         print.log("✓ 单数字模式补偿:假设AI图像宽度≈750,缩放系数=" + 图像缩放系数.toFixed(2));
  970.         print.log("✓ 补偿后拖动距离=" + 拖动距离像素);
  971.     }
  972.    
  973.     验证码滑块距离 = {
  974.         x: 拖动距离像素,
  975.         y: 0
  976.     };

  977.     // 步骤13:切换回B站并拖动滑块
  978.     print.log("\n========== 步骤13:切换回B站并拖动滑块 ==========");
  979.    
  980.     agent.shell("input keyevent 187");
  981.     print.log("✓ 已按后台键打开任务列表");
  982.     sleep.second(秒 = 2);
  983.    
  984.     xml = 获取UI();
  985.     var biliIdx = xml.indexOf('哔哩哔哩');
  986.     if (biliIdx === -1) {
  987.         biliIdx = xml.indexOf('bilibili');
  988.     }
  989.     if (biliIdx === -1) {
  990.         biliIdx = xml.indexOf('B站');
  991.     }
  992.    
  993.     if (biliIdx !== -1) {
  994.         var 段 = xml.substring(biliIdx);
  995.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  996.         if (m) {
  997.             var clickX = (parseInt(m[1]) + parseInt(m[3])) / 2;
  998.             var clickY = (parseInt(m[2]) + parseInt(m[4])) / 2;
  999.             agent.click(clickX, clickY);
  1000.             print.log("✓ 已点击B站任务卡片,坐标(" + Math.round(clickX) + "," + Math.round(clickY) + ")");
  1001.         }
  1002.     } else {
  1003.         print.log("⚠ 未找到B站任务卡片,尝试直接打开");
  1004.         try {
  1005.             app.openApp(B站包名);
  1006.             print.log("✓ 已打开B站");
  1007.         } catch (e) {
  1008.             print.log("⚠ 打开B站失败:" + e.message);
  1009.         }
  1010.     }
  1011.     sleep.second(秒 = 3);

  1012.     xml = 获取UI();
  1013.     var 验证码区域左边界 = 屏幕宽 * 0.15;
  1014.    
  1015.     var 滑块轨道匹配 = xml.match(/<node[^>]*?text="拖动滑块完成拼图"[^>]*?bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  1016.     if (滑块轨道匹配) {
  1017.         验证码区域左边界 = parseInt(滑块轨道匹配[1]);
  1018.     }

  1019.     var 拖动距离 = 验证码滑块距离.x * 滑块校准系数;

  1020.     var startX = 验证码区域左边界 + 50;
  1021.     var startY = 屏幕高 * 0.42;
  1022.     var endX = startX + 拖动距离;
  1023.     var endY = startY;

  1024.     print.log("✓ 验证码区域左边界: " + 验证码区域左边界 + ", 拖动距离: " + 拖动距离);
  1025.     agent.swip(startX, startY, endX, endY, 2000);
  1026.     print.log("✓ 已拖动滑块,起点(" + Math.round(startX) + "," + Math.round(startY) + "),终点(" + Math.round(endX) + "," + Math.round(endY) + ")");
  1027. }

  1028. 主流程();

  1029. print.log("\n===== 元宝识别验证码拖动B站流程结束 =====");
复制代码



unto示例千问自动采集文章保存记事本nextnocontent
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

相关导读
信息发布软件示例千问自动采集文章保存记事本
示例千问自动采集文章保存记事本
信息发布软件豆包识别验证码加拖动验证码示例
豆包识别验证码加拖动验证码示例
信息发布软件豆包对话采集示例
豆包对话采集示例
信息发布软件启动自动百度贴吧发图片
启动自动百度贴吧发图片
信息发布软件自动百度贴吧示例
自动百度贴吧示例
信息发布软件代理模式简书自动流程
代理模式简书自动流程
信息发布软件启动极速版任务页看小说赚钱自动阅读
启动极速版任务页看小说赚钱自动阅读
信息发布软件agent代理模式功能小结
agent代理模式功能小结
信息发布软件完整苹果IOS小脚本文本输入与粘贴流程
完整苹果IOS小脚本文本输入与粘贴流程
信息发布软件AIWROK使用activity列表开关与进度条的协同交互
AIWROK使用activity列表开关与进度条的协同交互
群发软件苹果脚本找图后Detect对象各种方法演示
苹果脚本找图后Detect对象各种方法演示
群发软件苹果脚本网络API监控与数据管理工具
苹果脚本网络API监控与数据管理工具
群发软件IOS苹果脚本TXT文件读写H5日志打印完整示例
IOS苹果脚本TXT文件读写H5日志打印完整示例
群发软件AIWROK软件演示多线程创建暂停恢复
AIWROK软件演示多线程创建暂停恢复
群发软件AIWROK软件定时检查页面状态防止卡死技巧
AIWROK软件定时检查页面状态防止卡死技巧
群发软件安卓脚本runTime相关功能示例
安卓脚本runTime相关功能示例
群发软件floatUI实例秒显示秒关闭吐司功能
floatUI实例秒显示秒关闭吐司功能
群发软件苹果脚本HID多行实例粘帖板示例
苹果脚本HID多行实例粘帖板示例
群发软件安卓脚本HID节点查找完整方法示例
HID节点查找完整方法示例
群发软件AIWROK软件框架的抖音自动化营销系统
AIWROK软件框架的抖音自动化营销系统
群发软件赛博朋克任务控制中心H5示例
赛博朋克任务控制中心H5示例
群发软件苹果脚本现代深色UI设计风格
现代深色UI设计风格
群发软件AIWROK软件智能任务监控悬浮窗
AIWROK软件智能任务监控悬浮窗
群发软件AIWROK软件事件监听示例
AIWROK软件事件监听示例
群发软件QZ掘金原生UI界面
QZ掘金原生UI界面
群发软件安卓脚本auto方法完整示例
安卓脚本auto方法完整示例
群发软件安卓脚本暂停弹出确认对话框
安卓脚本暂停弹出确认对话框
群发软件苹果iOS脚本天气信息查询工具
苹果iOS脚本天气信息查询工具
群发软件安卓脚本简化版H5日志输出窗口
安卓脚本简化版H5日志输出窗口
群发软件安卓脚本简化版H5日志输出窗口
安卓脚本简化版H5日志输出窗口
群发软件安卓脚本应用重置、代理模式监控及补丁升级
安卓脚本应用重置、代理模式监控及补丁升级
群发软件安卓脚本里的打开关闭安装以及卡密授权信息
安卓脚本里的打开关闭安装以及卡密授权信息
群发软件AIWROK软件脚本GET下载文件并检测0KB工具
AIWROK软件脚本GET下载文件并检测0KB工具
群发软件安卓脚本HID按键方法完整示例
安卓脚本HID按键方法完整示例
群发软件AIWROK软件键鼠HID滑动所有方法功能演示
AIWROK软件键鼠HID滑动所有方法功能演示
群发软件苹果脚本里HID的5种滑动方法的使用
苹果脚本里HID的5种滑动方法的使用
群发软件苹果脚本示例7种不同的OCR识别和点击方法
苹果脚本示例7种不同的OCR识别和点击方法
群发软件AIWROK软件安卓脚本FTP上传下载例子
AIWROK软件安卓脚本FTP上传下载例子
群发软件AIWROK软件脚本JSON转换示例
AIWROK软件脚本JSON转换示例
群发软件AIWROK软件运算符高级应用实例
AIWROK软件运算符高级应用实例
群发软件JavaScript语法小示例
JavaScript语法小示例
群发软件展示JavaScript各种语句标识符的实际应用
展示JavaScript各种语句标识符的实际应用
群发软件AIWROK条件语句实用示例智能活动推荐系统
AIWROK条件语句实用示例智能活动推荐系统
群发软件AIWROK软件示例数组方法实战应用
AIWROK软件示例数组方法实战应用
群发软件示例JavaScript的 try-catch-finally-throw用法
示例JavaScript的 try-catch-finally-throw用法
群发软件JavaScript 高级错误处理实战示例
JavaScript 高级错误处理实战示例
群发软件安卓脚本AIWROK软件示例JS函数高级用法
安卓脚本AIWROK软件示例JS函数高级用法
群发软件AIWROK环境JavaScript编码规范完整示例
AIWROK环境JavaScript编码规范完整示例
群发软件安卓脚本示例实时截图判断页面变化
安卓脚本示例实时截图判断页面变化
群发软件苹果脚本7种不同的OCR识别
苹果脚本7种不同的OCR识别
群发软件安卓脚本多变的function用法
安卓脚本多变的function用法
群发软件苹果脚本示例Config配置H5集成
苹果脚本示例Config配置H5集成
群发软件安卓脚本类型判断与Boolean对象综合示例
安卓脚本类型判断与Boolean对象综合示例
群发软件线程全局变量H5可视化控制台
线程全局变量H5可视化控制台
群发软件秒吐司快速显示和关闭的UI提示窗口
秒吐司快速显示和关闭的UI提示窗口
群发软件苹果脚本里H5 里的 window.at.callFun 示例
苹果脚本里H5 里的 window.at.callFun 示例
群发软件H5日志打印运行过程例子
H5日志打印运行过程例子
群发软件AIWROK软件字符串方法实用案例
AIWROK软件字符串方法实用案例
群发软件HID贝塞尔曲线运动控制器
HID贝塞尔曲线运动控制器
群发软件AIWROK苹果脚本sleep方法综合实战示例
AIWROK苹果脚本sleep方法综合实战示例
群发软件苹果脚本Line控件的多种创意用法和实际应用场景
苹果脚本Line控件的多种创意用法和实际应用场景
群发软件苹果脚本toast高级应用综合示例
苹果脚本toast高级应用综合示例
群发软件苹果智能OCR自动化助手
苹果智能OCR自动化助手
群发软件苹果脚本UI超快速点击示例
苹果脚本UI超快速点击示例
群发软件展示时间戳的各种复杂处理方法
展示时间戳的各种复杂处理方法

QQ|( 京ICP备09078825号 )

本网站信息发布软件,是可以发布论坛,发送信息到各大博客,各大b2b软件自动发布,好不夸张的说:只要手工能发在电脑打开IE能发的网站,用这个宣传软件就可以仿制动作,进行推送发到您想发送的B2B网站或是信息发布平台上,不管是后台,还是前台,都可以进行最方便的广告发布,这个广告发布软件,可以按月购买,还可以试用软件,对网站的验证码也可以完全自动对信息发布,让客户自动找上门,使企业轻松实现b2b发布,这个信息发布软件,均是本站原创正版开发,拥有正版的血统,想要新功能,欢迎提意见给我,一好的分类信息群发软件在手,舍我其谁。QQ896757558

GMT+8, 2026-7-16 07:07 , Processed in 0.907839 second(s), 50 queries .

宣传软件--信息发布软件--b2b软件广告发布软件

快速回复 返回顶部 返回列表