注册 登录
发贴工具
查看: 13|回复: 0
打印 上一主题 下一主题

[24小时收录超级好的网站] 豆包识别验证码加拖动验证码示例

[复制链接]

2582

主题

2630

帖子

1万

积分

积分
15668
跳转到指定楼层
楼主
豆包识别验证码加拖动验证码示例
豆包识别验证码加拖动验证码示例 群发软件发帖工具
  1. // AIWROK 自动化流程:全屏截图 → 启动豆包 → 发送截图 → 等待AI回答 → 采集回答内容 → 保存到文件
  2. // 全程使用 agent.getXml() 获取界面源码
  3. // 包名:com.larus.nova(豆包)
  4. //
  5. // 使用说明:
  6. //   1. 在需要截图的页面运行脚本
  7. //   2. 脚本会自动截图并发送给豆包分析
  8. //   3. 采集结果保存到 /sdcard/豆包截图分析.json

  9. print.log("===== 豆包截图发送流程启动 =====");
  10. print.time();

  11. // ========== 配置区 ==========
  12. var 豆包包名 = "com.larus.nova";
  13. var 截图保存路径 = "/sdcard/screenshot.png";

  14. // 发送后等待AI回答的最大秒数(整体超时)
  15. var 等待回答超时秒 = 8;

  16. // 检测到新回答出现后,再等待多少秒让回答输出完整
  17. var 回答输出等待秒 = 10;

  18. // 验证码滑块拖动校准系数(根据实际效果调整,默认1.0)
  19. // 如果拖动距离偏大,调小此值(如0.95);如果偏小,调大此值(如1.05)
  20. var 滑块校准系数 = 1.0;

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

  27. // ========== 工具函数 ==========

  28. function 获取UI() {
  29.     var xml = agent.getXml();
  30.     return "" + xml;
  31. }

  32. function 字符串长度(s) {
  33.     var str = "" + s;
  34.     return str.length;
  35. }

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

  52. function 采集AI回答列表(xml, 严格过滤) {
  53.     if (严格过滤 === undefined) 严格过滤 = true;
  54.     var xmlStr = "" + xml;
  55.     var 回答列表 = [];

  56.     var listIdx = xmlStr.indexOf('id/message_list"');
  57.     if (listIdx === -1) {
  58.         print.log("⚠ 未找到消息列表节点");
  59.         return 回答列表;
  60.     }

  61.     var 后面 = xmlStr.substring(listIdx);
  62.     var 位置 = 0;
  63.     while (true) {
  64.         var cvIdx = 后面.indexOf('id/content_view"', 位置);
  65.         if (cvIdx === -1) break;

  66.         var 段 = 后面.substring(cvIdx);
  67.         
  68.         var cvBounds = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  69.         var isAI = false;
  70.         if (cvBounds) {
  71.             var cvX1 = parseInt(cvBounds[1]);
  72.             if (cvX1 < 屏幕宽 / 2) {
  73.                 isAI = true;
  74.             }
  75.         }

  76.         var 标签结束 = 段.indexOf(">");
  77.         if (标签结束 === -1) break;
  78.         var 子段 = 段.substring(标签结束 + 1);

  79.         var 文本匹配 = 子段.match(/<node[^>]*?text="([^"]+)"[^>]*?class="android\.widget\.TextView"[^>]*?\/?>/);
  80.         if (!文本匹配) {
  81.             文本匹配 = 子段.match(/<node[^>]*?class="android\.widget\.TextView"[^>]*?text="([^"]+)"[^>]*?\/?>/);
  82.         }

  83.         if (文本匹配 && 文本匹配[1]) {
  84.             var 原始文本 = 文本匹配[1];
  85.             var 解码文本 = 解码HTML实体(原始文本);
  86.             if (严格过滤) {
  87.                 if (isAI && 字符串长度(解码文本) > 0) {
  88.                     回答列表.push(解码文本);
  89.                 }
  90.             } else {
  91.                 if (字符串长度(解码文本) > 0) {
  92.                     回答列表.push(解码文本);
  93.                 }
  94.             }
  95.         }

  96.         位置 = cvIdx + 30;
  97.     }

  98.     return 回答列表;
  99. }

  100. function 获取当前最后AI回答(xml) {
  101.     var 回答列表 = 采集AI回答列表(xml);
  102.     if (回答列表.length === 0) return "";
  103.     return 回答列表[回答列表.length - 1];
  104. }

  105. // 全屏截图(使用shell命令)
  106. function 全屏截图(保存路径) {
  107.     try {
  108.         var result = agent.shell("screencap -p " + 保存路径);
  109.         print.log("✓ 截图命令执行:" + result);
  110.         
  111.         var lsResult = agent.shell("ls -la " + 保存路径);
  112.         print.log("✓ 截图文件检查:" + lsResult);
  113.         
  114.         return true;
  115.     } catch (e) {
  116.         print.log("⚠ 截图失败:" + e.message);
  117.         return false;
  118.     }
  119. }

  120. // 查找豆包的加号按钮(优先右下角 action_menu_entrance)
  121. function 查找加号按钮(xml) {
  122.     var xmlStr = "" + xml;
  123.    
  124.     var menuEntranceIdx = xmlStr.indexOf('id/action_menu_entrance"');
  125.     if (menuEntranceIdx !== -1) {
  126.         var 段 = xmlStr.substring(menuEntranceIdx);
  127.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  128.         if (m) {
  129.             return {
  130.                 x: (parseInt(m[1]) + parseInt(m[3])) / 2,
  131.                 y: (parseInt(m[2]) + parseInt(m[4])) / 2
  132.             };
  133.         }
  134.     }

  135.     var entranceIdx = xmlStr.indexOf('id/action_entrance"');
  136.     if (entranceIdx !== -1) {
  137.         var 段2 = xmlStr.substring(entranceIdx);
  138.         var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  139.         if (m2) {
  140.             return {
  141.                 x: (parseInt(m2[1]) + parseInt(m2[3])) / 2,
  142.                 y: (parseInt(m2[2]) + parseInt(m2[4])) / 2
  143.             };
  144.         }
  145.     }

  146.     var plusIdx = xmlStr.indexOf('text="+"');
  147.     if (plusIdx !== -1) {
  148.         var 段3 = xmlStr.substring(plusIdx);
  149.         var m3 = 段3.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  150.         if (m3) {
  151.             return {
  152.                 x: (parseInt(m3[1]) + parseInt(m3[3])) / 2,
  153.                 y: (parseInt(m3[2]) + parseInt(m3[4])) / 2
  154.             };
  155.         }
  156.     }

  157.     var attachIdx = xmlStr.indexOf('content-desc="附件"');
  158.     if (attachIdx === -1) {
  159.         attachIdx = xmlStr.indexOf('content-desc="添加"');
  160.     }
  161.     if (attachIdx !== -1) {
  162.         var 段4 = xmlStr.substring(attachIdx);
  163.         var m4 = 段4.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  164.         if (m4) {
  165.             return {
  166.                 x: (parseInt(m4[1]) + parseInt(m4[3])) / 2,
  167.                 y: (parseInt(m4[2]) + parseInt(m4[4])) / 2
  168.             };
  169.         }
  170.     }

  171.     return null;
  172. }

  173. function 查找输入框中心(xml) {
  174.     var xmlStr = "" + xml;
  175.     var idx = xmlStr.indexOf('id/input_text"');
  176.     if (idx === -1) return null;

  177.     var 段 = xmlStr.substring(idx);
  178.     var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  179.     if (!m) return null;

  180.     var x1 = parseInt(m[1]);
  181.     var y1 = parseInt(m[2]);
  182.     var x2 = parseInt(m[3]);
  183.     var y2 = parseInt(m[4]);
  184.     return {
  185.         x: (x1 + x2) / 2,
  186.         y: (y1 + y2) / 2
  187.     };
  188. }

  189. function 粘贴文本(文本) {
  190.     try {
  191.         Clipboard.copy("" + 文本);
  192.     } catch (e) {
  193.         print.log("⚠ Clipboard.copy 失败:" + e.message);
  194.     }
  195.     sleep.millisecond(毫秒 = 300);

  196.     try {
  197.         agent.shell("service call clipboard 3 i32 1 s16 '" + 文本 + "' i32 0");
  198.     } catch (e2) {
  199.         // 忽略错误
  200.     }
  201.     sleep.millisecond(毫秒 = 300);

  202.     agent.shell("input keyevent 279");
  203.     sleep.second(秒 = 1);
  204.     print.log("✓ 已粘贴文本:" + 文本);
  205. }

  206. function 是否已进入相机页面(xml) {
  207.     var xmlStr = "" + xml;
  208.     return xmlStr.indexOf('id/focus_container"') !== -1 && xmlStr.indexOf('id/suggest_action_bar"') === -1;
  209. }

  210. function 是否已进入图片预览页面(xml) {
  211.     var xmlStr = "" + xml;
  212.     return xmlStr.indexOf('id/focus_container"') !== -1 && xmlStr.indexOf('id/suggest_action_bar"') !== -1;
  213. }

  214. function 是否已进入图片选择列表页面(xml) {
  215.     var xmlStr = "" + xml;
  216.     return xmlStr.indexOf('id/media_viewpager"') !== -1 || xmlStr.indexOf('id/media_list"') !== -1;
  217. }

  218. function 查找相册选项(xml) {
  219.     var xmlStr = "" + xml;
  220.    
  221.     if (是否已进入图片预览页面(xml)) {
  222.         return { x: -1, y: -1, 已进入预览页: true };
  223.     }
  224.    
  225.     if (是否已进入图片选择列表页面(xml)) {
  226.         return { x: -1, y: -1, 已进入选择页: true };
  227.     }
  228.    
  229.     var albumIdx = xmlStr.indexOf('text="相册"');
  230.     if (albumIdx === -1) {
  231.         albumIdx = xmlStr.indexOf('text="图片"');
  232.     }
  233.     if (albumIdx === -1) {
  234.         albumIdx = xmlStr.indexOf('text="照片"');
  235.     }
  236.     if (albumIdx === -1) {
  237.         albumIdx = xmlStr.indexOf('text="所有照片"');
  238.     }
  239.     if (albumIdx === -1) {
  240.         albumIdx = xmlStr.indexOf('text="从相册选择"');
  241.     }
  242.     if (albumIdx === -1) {
  243.         albumIdx = xmlStr.indexOf('text="选择图片"');
  244.     }
  245.     if (albumIdx !== -1) {
  246.         var 段 = xmlStr.substring(albumIdx);
  247.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  248.         if (m) {
  249.             return {
  250.                 x: (parseInt(m[1]) + parseInt(m[3])) / 2,
  251.                 y: (parseInt(m[2]) + parseInt(m[4])) / 2
  252.             };
  253.         }
  254.     }

  255.     var albumIconIdx = xmlStr.indexOf('content-desc="相册"');
  256.     if (albumIconIdx === -1) {
  257.         albumIconIdx = xmlStr.indexOf('content-desc="图片"');
  258.     }
  259.     if (albumIconIdx !== -1) {
  260.         var 段2 = xmlStr.substring(albumIconIdx);
  261.         var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  262.         if (m2) {
  263.             return {
  264.                 x: (parseInt(m2[1]) + parseInt(m2[3])) / 2,
  265.                 y: (parseInt(m2[2]) + parseInt(m2[4])) / 2
  266.             };
  267.         }
  268.     }

  269.     return null;
  270. }

  271. // 查找图片选择器中的第一张图片(刚截的图)
  272. function 查找第一张图片(xml) {
  273.     var xmlStr = "" + xml;
  274.    
  275.     var thumbnailIdx = xmlStr.indexOf('id/iv_thumbnail"');
  276.     if (thumbnailIdx !== -1) {
  277.         var 段 = xmlStr.substring(thumbnailIdx);
  278.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  279.         if (m) {
  280.             return {
  281.                 x: (parseInt(m[1]) + parseInt(m[3])) / 2,
  282.                 y: (parseInt(m[2]) + parseInt(m[4])) / 2
  283.             };
  284.         }
  285.     }

  286.     var imageIdx = xmlStr.indexOf('class="android.widget.ImageView"');
  287.     if (imageIdx !== -1) {
  288.         var 段2 = xmlStr.substring(imageIdx);
  289.         var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  290.         if (m2) {
  291.             var x = (parseInt(m2[1]) + parseInt(m2[3])) / 2;
  292.             var y = (parseInt(m2[2]) + parseInt(m2[4])) / 2;
  293.             if (y > 400) {
  294.                 return { x: x, y: y };
  295.             }
  296.         }
  297.     }

  298.     return null;
  299. }

  300. // 查找发送按钮
  301. function 查找发送按钮中心(xml) {
  302.     var xmlStr = "" + xml;

  303.     var sendTextIdx = xmlStr.indexOf('text="发送"');
  304.     if (sendTextIdx !== -1) {
  305.         var 段 = xmlStr.substring(sendTextIdx);
  306.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  307.         if (m) {
  308.             return {
  309.                 x: (parseInt(m[1]) + parseInt(m[3])) / 2,
  310.                 y: (parseInt(m[2]) + parseInt(m[4])) / 2
  311.             };
  312.         }
  313.     }

  314.     var sendIdIdx = xmlStr.indexOf('id/action_send"');
  315.     if (sendIdIdx !== -1) {
  316.         var 段2 = xmlStr.substring(sendIdIdx);
  317.         var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  318.         if (m2) {
  319.             return {
  320.                 x: (parseInt(m2[1]) + parseInt(m2[3])) / 2,
  321.                 y: (parseInt(m2[2]) + parseInt(m2[4])) / 2
  322.             };
  323.         }
  324.     }

  325.     var rightIconIdx = xmlStr.indexOf('id/right_icon"');
  326.     if (rightIconIdx !== -1) {
  327.         var 段3 = xmlStr.substring(rightIconIdx);
  328.         var m3 = 段3.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  329.         if (m3) {
  330.             var y = (parseInt(m3[2]) + parseInt(m3[4])) / 2;
  331.             if (y > 3000) {
  332.                 return {
  333.                     x: (parseInt(m3[1]) + parseInt(m3[3])) / 2,
  334.                     y: y
  335.                 };
  336.             }
  337.         }
  338.     }

  339.     return null;
  340. }

  341. function 查找并点击展开按钮(xml) {
  342.     var xmlStr = "" + xml;
  343.    
  344.     var expandIdx = xmlStr.indexOf('content-desc="展开"');
  345.     if (expandIdx === -1) {
  346.         expandIdx = xmlStr.indexOf('content-desc="更多"');
  347.     }
  348.     if (expandIdx === -1) {
  349.         expandIdx = xmlStr.indexOf('content-desc="收起"');
  350.     }
  351.    
  352.     if (expandIdx !== -1) {
  353.         var 段 = xmlStr.substring(expandIdx);
  354.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  355.         if (m) {
  356.             var x = (parseInt(m[1]) + parseInt(m[3])) / 2;
  357.             var y = (parseInt(m[2]) + parseInt(m[4])) / 2;
  358.             agent.click(x, y);
  359.             print.log("✓ 已点击展开按钮(content-desc),坐标(" + Math.round(x) + "," + Math.round(y) + ")");
  360.             sleep.second(秒 = 1);
  361.             return true;
  362.         }
  363.     }

  364.     var textExpandIdx = xmlStr.indexOf('text="展开"');
  365.     if (textExpandIdx === -1) {
  366.         textExpandIdx = xmlStr.indexOf('text="更多"');
  367.     }
  368.     if (textExpandIdx !== -1) {
  369.         var 段2 = xmlStr.substring(textExpandIdx);
  370.         var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  371.         if (m2) {
  372.             var x2 = (parseInt(m2[1]) + parseInt(m2[3])) / 2;
  373.             var y2 = (parseInt(m2[2]) + parseInt(m2[4])) / 2;
  374.             agent.click(x2, y2);
  375.             print.log("✓ 已点击展开按钮(文本匹配),坐标(" + Math.round(x2) + "," + Math.round(y2) + ")");
  376.             sleep.second(秒 = 1);
  377.             return true;
  378.         }
  379.     }

  380.     return false;
  381. }

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

  386.     var xml = 获取UI();
  387.     var 初始列表 = 采集AI回答列表(xml, false);
  388.     发送前回答数量 = 初始列表.length;
  389.     print.log("发送前AI回答数量:" + 发送前回答数量);

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

  393.         xml = 获取UI();

  394.         var 回答列表 = 采集AI回答列表(xml, false);
  395.         
  396.         if (回答列表.length > 发送前回答数量) {
  397.             print.log("✓ 检测到新回答(" + 已耗时 + "秒),数量从" + 发送前回答数量 + "增加到" + 回答列表.length);
  398.             sleep.second(秒 = 3);
  399.             
  400.             xml = 获取UI();
  401.             var 最终列表 = 采集AI回答列表(xml, false);
  402.             if (最终列表.length > 0) {
  403.                 var 最终文本 = 最终列表[最终列表.length - 1];
  404.                 print.log("✓ 采集成功,返回结果:" + 最终文本);
  405.                 return 最终文本;
  406.             }
  407.         }
  408.     }

  409.     print.log("⚠ 等待AI回答超时(" + 等待回答超时秒 + "秒),尝试返回当前内容");
  410.     xml = 获取UI();
  411.     var 兜底列表 = 采集AI回答列表(xml, false);
  412.     if (兜底列表.length > 0) {
  413.         var 兜底文本 = 兜底列表[兜底列表.length - 1];
  414.         print.log("✓ 超时兜底:返回当前采集到的回答:" + 兜底文本);
  415.         return 兜底文本;
  416.     }
  417.     return null;
  418. }

  419. function 格式化对话(对话列表) {
  420.     var 数据 = {
  421.         "采集时间": new Date().toString(),
  422.         "对话轮数": 对话列表.length,
  423.         "对话记录": []
  424.     };
  425.    
  426.     for (var i = 0; i < 对话列表.length; i++) {
  427.         数据.对话记录.push({
  428.             "序号": i + 1,
  429.             "角色": 对话列表[i].角色,
  430.             "内容": 对话列表[i].内容
  431.         });
  432.     }
  433.    
  434.     return JSON.stringify(数据, null, 2);
  435. }

  436. function 写入文件(文件路径, 内容) {
  437.     try {
  438.         var str = "" + 内容;
  439.         var fos = new java.io.FileOutputStream(文件路径);
  440.         fos.write(str.getBytes("UTF-8"));
  441.         fos.close();
  442.         print.log("✓ 已写入文件(JSON格式):" + 文件路径);
  443.         
  444.         var catResult = agent.shell("cat " + 文件路径 + " | head -2");
  445.         print.log("✓ cat验证结果:" + catResult);
  446.         
  447.         return true;
  448.     } catch (e) {
  449.         print.log("⚠ JSON写入异常:" + e.message);
  450.     }

  451.     print.log("✗ 写入文件失败:" + 文件路径);
  452.     return false;
  453. }

  454. function 主流程() {
  455.     // 步骤1:全屏截图
  456.     print.log("\n========== 步骤1:全屏截图 ==========");
  457.     var 截图成功 = 全屏截图(截图保存路径);
  458.     if (!截图成功) {
  459.         print.log("✗ 截图失败,退出流程");
  460.         print.log("===== 豆包截图发送流程结束 =====");
  461.         return;
  462.     }

  463.     // 步骤2:启动豆包APP
  464.     print.log("\n========== 步骤2:启动豆包APP ==========");
  465.     try {
  466.         app.openApp(豆包包名);
  467.         print.log("✓ 已启动豆包");
  468.     } catch (e) {
  469.         print.log("⚠ 启动失败:" + e.message);
  470.     }
  471.     sleep.second(秒 = 5);

  472.     // 步骤3:确认进入对话页面
  473.     print.log("\n========== 步骤3:确认进入对话页面 ==========");
  474.     var xml = 获取UI();
  475.     if (xml.indexOf("message_list") === -1) {
  476.         print.log("⚠ 当前页面可能不是豆包对话页,再次等待");
  477.         sleep.second(秒 = 3);
  478.         xml = 获取UI();
  479.     }

  480.     if (xml.indexOf("message_list") !== -1) {
  481.         print.log("✓ 已进入豆包对话页面");
  482.     } else {
  483.         print.log("⚠ 未检测到消息列表");
  484.     }

  485.     // 步骤4:记录发送前的最后一条AI回答(作为检测基线)
  486.     var 发送前最后文本 = 获取当前最后AI回答(xml);

  487.     // 步骤5:点击加号按钮打开附件菜单
  488.     print.log("\n========== 步骤5:打开附件菜单 ==========");
  489.     var 加号按钮 = 查找加号按钮(xml);
  490.     if (加号按钮) {
  491.         agent.click(加号按钮.x, 加号按钮.y);
  492.         print.log("✓ 已点击action_entrance按钮,坐标(" + Math.round(加号按钮.x) + "," + Math.round(加号按钮.y) + ")");
  493.     } else {
  494.         print.log("⚠ 未找到加号按钮,尝试点击输入框左侧区域");
  495.         var inputIdx = xml.indexOf('id/speak_area"');
  496.         if (inputIdx !== -1) {
  497.             var 段 = xml.substring(inputIdx);
  498.             var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  499.             if (m) {
  500.                 var speakLeft = parseInt(m[1]);
  501.                 var speakY = (parseInt(m[2]) + parseInt(m[4])) / 2;
  502.                 agent.click(speakLeft - 50, speakY);
  503.                 print.log("✓ 已点击输入框左侧区域");
  504.             }
  505.         }
  506.     }
  507.     sleep.second(秒 = 2);

  508.     // 步骤6:等待页面跳转并处理图片选择
  509.     print.log("\n========== 步骤6:处理图片选择页面 ==========");
  510.     var 当前页面状态 = "未知";
  511.     var 尝试次数 = 0;
  512.     while (当前页面状态 === "未知" && 尝试次数 < 5) {
  513.         sleep.second(秒 = 2);
  514.         xml = 获取UI();
  515.         
  516.         if (是否已进入图片预览页面(xml)) {
  517.             当前页面状态 = "预览页";
  518.             print.log("✓ 已进入图片预览页面");
  519.         } else if (是否已进入图片选择列表页面(xml)) {
  520.             当前页面状态 = "选择列表";
  521.             print.log("✓ 已进入图片选择列表页面");
  522.         } else if (是否已进入相机页面(xml)) {
  523.             print.log("✓ 已进入相机页面,点击左下角图片缩略图进入相册");
  524.             agent.click(屏幕宽 * 0.15, 屏幕高 * 0.95);
  525.             print.log("✓ 已点击左下角图片缩略图");
  526.             continue;
  527.         } else {
  528.             var 相册选项 = 查找相册选项(xml);
  529.             if (相册选项 && !相册选项.已进入预览页 && !相册选项.已进入选择页) {
  530.                 print.log("✓ 找到相册选项,准备点击");
  531.                 agent.click(相册选项.x, 相册选项.y);
  532.                 print.log("✓ 已点击相册选项,坐标(" + Math.round(相册选项.x) + "," + Math.round(相册选项.y) + ")");
  533.                 continue;
  534.             }
  535.         }
  536.         尝试次数++;
  537.     }
  538.    
  539.     if (当前页面状态 === "选择列表") {
  540.         var 第一张图片 = 查找第一张图片(xml);
  541.         if (第一张图片) {
  542.             agent.click(第一张图片.x, 第一张图片.y);
  543.             print.log("✓ 已选择第一张图片,坐标(" + Math.round(第一张图片.x) + "," + Math.round(第一张图片.y) + ")");
  544.             sleep.second(秒 = 2);
  545.             
  546.             xml = 获取UI();
  547.             if (是否已进入图片预览页面(xml)) {
  548.                 当前页面状态 = "预览页";
  549.                 print.log("✓ 已进入图片预览页面");
  550.             }
  551.         }
  552.     }

  553.     // 步骤7:粘贴文字到输入框(选择图片后马上粘贴)
  554.     print.log("\n========== 步骤7:粘贴文字询问拖动距离坐标 ==========");
  555.     xml = 获取UI();
  556.     var 输入框 = 查找输入框中心(xml);
  557.     if (输入框) {
  558.         agent.click(输入框.x, 输入框.y);
  559.         sleep.second(秒 = 1);
  560.         粘贴文本("请告诉我验证码滑块需要拖动的距离坐标,只输出坐标数字,不要其他文字");
  561.     } else {
  562.         print.log("⚠ 未找到输入框");
  563.     }
  564.     sleep.second(秒 = 2);

  565.     // 步骤8:发送图片和文字
  566.     print.log("\n========== 步骤8:发送图片和文字 ==========");
  567.     if (当前页面状态 === "预览页") {
  568.         var confirmX = 屏幕宽 * 0.5;
  569.         var confirmY = 屏幕高 * 0.92;
  570.         agent.click(confirmX, confirmY);
  571.         print.log("✓ 已点击预览页底部中间白色对勾确认按钮,坐标(" + Math.round(confirmX) + "," + Math.round(confirmY) + ")");
  572.         sleep.second(秒 = 3);
  573.         xml = 获取UI();
  574.     }
  575.    
  576.     var sendBtn = 查找发送按钮中心(xml);
  577.     if (sendBtn) {
  578.         agent.click(sendBtn.x, sendBtn.y);
  579.         print.log("✓ 已点击对话页面发送按钮,坐标(" + Math.round(sendBtn.x) + "," + Math.round(sendBtn.y) + ")");
  580.     } else {
  581.         var actionSendIdx = xml.indexOf('id/action_send"');
  582.         if (actionSendIdx !== -1) {
  583.             var 段 = xml.substring(actionSendIdx);
  584.             var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  585.             if (m) {
  586.                 var sendX = (parseInt(m[1]) + parseInt(m[3])) / 2;
  587.                 var sendY = (parseInt(m[2]) + parseInt(m[4])) / 2;
  588.                 agent.click(sendX, sendY);
  589.                 print.log("✓ 已点击action_send按钮,坐标(" + Math.round(sendX) + "," + Math.round(sendY) + ")");
  590.             }
  591.         }
  592.     }
  593.     sleep.second(秒 = 5);

  594.     // 步骤9:记录发送后的基线文本
  595.     print.log("\n========== 步骤9:记录基线文本 ==========");
  596.     xml = 获取UI();
  597.     发送前最后文本 = 获取当前最后AI回答(xml);
  598.     print.log("发送前最后文本长度:" + 字符串长度(发送前最后文本));

  599.     // 步骤10:等待AI回答
  600.     print.log("\n========== 步骤10:等待AI回答 ==========");

  601.     var 新回答文本 = 等待AI回答完成(发送前最后文本);

  602.     // 步骤11:解析坐标并保存为全局变量
  603.     print.log("\n========== 步骤11:解析坐标 ==========");
  604.    
  605.     if (新回答文本 && 字符串长度(新回答文本) > 0) {
  606.         print.log("✓ 采集到AI回答");
  607.         print.log("--- 采集内容开始 ---");
  608.         print.log(新回答文本);
  609.         print.log("--- 采集内容结束 ---");
  610.         
  611.         var 坐标匹配 = 新回答文本.match(/(\d+)\s*[,,]\s*(\d+)/);
  612.         if (坐标匹配) {
  613.             验证码滑块距离 = {
  614.                 x: parseInt(坐标匹配[1]),
  615.                 y: parseInt(坐标匹配[2])
  616.             };
  617.             print.log("✓ 提取到坐标:(" + 验证码滑块距离.x + ", " + 验证码滑块距离.y + ")");
  618.         } else {
  619.             var 单个数字匹配 = 新回答文本.match(/(\d+)/);
  620.             if (单个数字匹配) {
  621.                 验证码滑块距离 = {
  622.                     x: parseInt(单个数字匹配[1]),
  623.                     y: 0
  624.                 };
  625.                 print.log("✓ 提取到单个数字:" + 验证码滑块距离.x);
  626.             } else {
  627.                 验证码滑块距离 = null;
  628.                 print.log("⚠ 未提取到坐标");
  629.             }
  630.         }
  631.     } else {
  632.         验证码滑块距离 = null;
  633.         print.log("⚠ 未能采集到新回答");
  634.     }

  635.     // 步骤12:切换回B站并拖动验证码滑块
  636.     if (验证码滑块距离 && 验证码滑块距离.x > 0) {
  637.         print.log("\n========== 步骤12:切换回B站并拖动滑块 ==========");
  638.         
  639.         agent.shell("input keyevent 187");
  640.         print.log("✓ 已按后台键打开任务列表");
  641.         sleep.second(秒 = 2);

  642.         xml = 获取UI();
  643.         var biliIdx = xml.indexOf('哔哩哔哩');
  644.         if (biliIdx === -1) {
  645.             biliIdx = xml.indexOf('bilibili');
  646.         }
  647.         
  648.         if (biliIdx !== -1) {
  649.             var 段 = xml.substring(biliIdx);
  650.             var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  651.             if (m) {
  652.                 var clickX = (parseInt(m[1]) + parseInt(m[3])) / 2;
  653.                 var clickY = (parseInt(m[2]) + parseInt(m[4])) / 2;
  654.                 agent.click(clickX, clickY);
  655.                 print.log("✓ 已点击B站任务卡片,坐标(" + Math.round(clickX) + "," + Math.round(clickY) + ")");
  656.             }
  657.         } else {
  658.             print.log("⚠ 未找到B站任务卡片,尝试直接打开");
  659.             try {
  660.                 app.openApp("tv.danmaku.bili");
  661.                 print.log("✓ 已打开B站");
  662.             } catch (e) {
  663.                 print.log("⚠ 打开B站失败:" + e.message);
  664.             }
  665.         }
  666.         sleep.second(秒 = 3);

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

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

  675.         var startX = 验证码区域左边界 + 50;
  676.         var startY = 屏幕高 * 0.42;
  677.         var endX = startX + 拖动距离;
  678.         var endY = startY;

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

  683.     print.log("\n===== 豆包截图发送流程结束 =====");
  684. }

  685. 主流程();
复制代码



unto豆包对话采集示例nextnocontent
回复

使用道具 举报

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

本版积分规则

相关导读了
    采集亚马逊正版群发工具有没有?
    Apr.20旅行X心语今天来说说YYPOST新功能的一个灵活用法,采集亚马逊商品信息,并且获得排名的软件,亚马逊现在越来越多客户做,淘宝的水是越来越清了,以前做电商的客户,现在都转战到外国,最赚钱的要数一些客户往亚马逊里堆了吧,拿我这个YYPOST的客户,最多的是采集,分析排名,刷价格,刷数量,改价,刷访问量等等技术

    企业发展B2B网站有什么东东软件可以发呢
    标题企业发展网B2B软件,现在虽然B2B网站收录不错,可愁的是心急的人们,他们太想一口吃撑胖子了,发帖宣传虽然不能像佛系那样淡定,但也不能像跑火车那般急躁对待,自己内容不收录,完全是自己操作内容问题,可以参考一下别人的内容是怎么弄的,然后自己要试着转变,而且收录这个内容,常常会变化的,不是一种规则就吃到老

    搜房天下房聊软件哪一个好呢
    本帖最后由 发帖软件 于 2019-5-22 16:15 编辑 2搜房天下群发房聊信息软件,开始本来打算做58同城的,但发一个就要一次点触验证码,这就让人没有感觉到存在的价值了吧,都是卖二手房和新房的搜房天下倒是可以发即时聊天信息,也没有发现他这个网站有啥子限制,登陆一个搜房天下账号,然后采集回来分类列表的网址,然后就一

    大家坛有没有好用的群发工具下载呢
    当你的笑容给我礼貌的招呼,大家坛全自动发帖软件,宣传推广是一场持久战,总是有一些人把软件用了一天,或是几个小时,就觉得自己付出太多了,那加进来的粉丝,或是流量,应该是和宣传多少成正比的,其实没有这么便宜的事,就像很多阅读量超过一百万的视频,或是电影,真正会在屏幕打赏的人不会超过三千,真正大额打赏给主

    群发正版软件中国塑料网
    中国塑料网群发软件YYPOST脚本下载地址,这个网站会有一个很奇怪的问题就是你在首页登陆无半个验证码,但在登陆网址登陆就会有一个验证码,所以我们灵活一些,在首页登陆就不用输入验证码了哈。网站秒收录比较高,但发的都是五金和建筑行业,先前有很多人都是发土建工程的大公司操作的,现在这个网站专为那个行业诞生的吧。

    OpenStreetMap网站正版2019年发帖工具下载
    本帖最后由 发帖软件 于 2019-5-21 11:13 编辑 OpenStreetMap网站全自动群发,OpenStreetMapOpenStreetMap(简称OSM,中文是公开地图)是一个网上地图协作计划,目标是创造一个内容自由且能让所有人编辑的世界地图。有的人编辑地图然后等收录,有的人发日志等收录,我们这里也是利用地图日志做为宣传的目标,简单的脚本理

    搜房天下全自动收短信全自动识别验证码注册账号软件
    房天下自动注册机,这个脚本是前几天发房聊的脚本廷伸品种,这个脚本能做到自动注册账号,自动保存账号,自动发房聊的效果,不过今天我们主要说一说怎么注册账号写脚本吧,这个搜房天天下的账号,可以发提问,可以发房聊,发论坛,发博客,还有发个人中心页都是有秒收的效果的,这样就省去了去买号,去乱花钱的效果了吧,而

    企业邮箱安卓端有什么APP软件可以发的呢
    请输入标题企业邮箱安卓发发送邮箱脚本,这个脚本是利用企业邮箱进行群发的,全程是一种模拟手工操作的过程,所以封号是很少的,而且企业邮箱群发到普通QQ邮箱不容易进垃圾箱中的,所以这个脚本也是这样的原理,不过最好是利用一些多开器,登陆多点的QQ邮箱账号会比较流畅一些,然后用软件一个一个的切换APP进行群发邮件会

    头条留评论软件有没有好用的呢?
    今天整一个今日头条留言软件,对于留言YYPOST是优势是比较大的存在,因为他往往专注一些下拉定位的优点,像今日头条这样,还是需要一些特殊下拉定位的,因为他新闻有长有短,有图有视频的,所以综合起来定位是比较难的,如果用POST也不是很轻松可以破解他的加密参数。这个脚本也是有一个不好的地方就是换号会比较麻烦,您电

    单网页生成神器
    最近新技术,网页生成机占领了整个网络的半壁江山,效果很疯狂,虽然不知道能持续多久,作为开发软件的领头者,一直在找收录的方法,一直在努力创新着,一直被人模仿,却从没有被超越过,这个网页生成机,已经出来有一段时间了,一直没有拿出来分享,醉过醉过,它是利用的一些小小收录漏洞整的,您最好用一些老站域名,进行

关闭
快速回复 返回列表 返回顶部
本站自动发贴软件,是现在最流行的做脚本软件,这种发贴工具,不但发贴收录快,而且抢占好的先机,完全自由编辑,实现针对性群发模拟操作,软件可以顶贴,也可以发贴,可以兼容支持Discuz、PHPWind、Dvbbs三大主流论坛,有手机验证码收件,邮件收发的功能,支持验证码识别,注册问题识别,多线程任务,自动上传头像,自动激活注册邮件,兼容防注册插件,本站软件原创正版,更新效率最快的原创软件。 『网络推广软件』『自动发帖软件』『 自动发帖