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

[24小时收录超级好的网站] 豆包对话采集示例

[复制链接]

2581

主题

2629

帖子

1万

积分

积分
15662
跳转到指定楼层
楼主
豆包对话采集示例
豆包对话采集示例 群发软件发帖工具

  1. // AIWROK 自动化流程:启动豆包 → 输入问题 → 点击发送 → 等待AI回答 → 采集回答内容 → 保存到文件
  2. // 全程使用 agent.getXml() 获取界面源码
  3. // 包名:com.larus.nova(豆包)
  4. //
  5. // 使用说明:
  6. //   1. 修改下方【配置区】中的"要发送的问题列表"
  7. //   2. 采集结果保存到 /sdcard/豆包对话记录.txt

  8. print.log("===== 豆包对话采集流程启动 =====");
  9. print.time();

  10. // ========== 配置区 ==========
  11. var 豆包包名 = "com.larus.nova";

  12. // 输出文件路径
  13. var 输出文件路径 = "/sdcard/豆包对话记录.txt";

  14. // 要发送的问题列表(按顺序发送)
  15. var 要发送的问题列表 = [
  16.     "你好,请用一句话介绍你自己",
  17.     "中国平安股票最近走势如何?",
  18.     "招商银行持有3年卖出需要交股息税吗?"
  19. ];

  20. // 发送后等待AI回答的最大秒数(整体超时,最长10秒)
  21. var 等待回答超时秒 = 10;

  22. // 检测到新回答出现后,再等待多少秒让回答尽量输出完整(然后直接返回)
  23. var 回答输出等待秒 = 8;

  24. // 每个问题之间的间隔秒数
  25. var 问题间隔秒 = 2;

  26. // ========== 获取设备信息 ==========
  27. var 屏幕宽 = screen.getScreenWidth();
  28. var 屏幕高 = screen.getScreenHeight();
  29. print.log("屏幕尺寸:" + 屏幕宽 + " x " + 屏幕高);
  30. print.log("代理状态:" + (agent.isOpen() ? "已开启" : "未开启"));

  31. // ========== 工具函数 ==========

  32. // 获取 UI XML 字符串(使用 agent.getXml(),强制转为字符串)
  33. function 获取UI() {
  34.     var xml = agent.getXml();
  35.     // agent.getXml() 返回对象,需强制转为字符串
  36.     return "" + xml;
  37. }

  38. // 字符串长度兼容函数(避免 Java String 对象 .length() 方法问题)
  39. function 字符串长度(s) {
  40.     var str = "" + s;
  41.     return str.length;
  42. }

  43. // HTML实体解码(豆包TextView中的换行符等会被编码为
  44. ' 等)
  45. function 解码HTML实体(s) {
  46.     var str = "" + s;
  47.     str = str.replace(/
  48. /g, "\n");
  49.     str = str.replace(/
  50. /g, "\r");
  51.     str = str.replace(/        /g, "\t");
  52.     str = str.replace(/'/g, "'");
  53.     str = str.replace(/"/g, '"');
  54.     str = str.replace(/"/g, '"');
  55.     str = str.replace(/'/g, "'");
  56.     str = str.replace(/&/g, "&");
  57.     str = str.replace(/</g, "<");
  58.     str = str.replace(/>/g, ">");
  59.     return str;
  60. }

  61. // 采集豆包 message_list 中所有 content_view 下的 TextView 文本(即AI回答)
  62. // 参数 严格过滤: true=排除短文本按钮等, false=不过滤(用于检测新回答出现,更灵敏)
  63. function 采集AI回答列表(xml, 严格过滤) {
  64.     if (严格过滤 === undefined) 严格过滤 = true;
  65.     var xmlStr = "" + xml;
  66.     var 回答列表 = [];

  67.     // 定位 message_list 节点
  68.     var listIdx = xmlStr.indexOf('id/message_list"');
  69.     if (listIdx === -1) {
  70.         print.log("⚠ 未找到消息列表节点,可能不在豆包对话页面");
  71.         return 回答列表;
  72.     }

  73.     // 截取 message_list 之后的部分
  74.     var 后面 = xmlStr.substring(listIdx);

  75.     // 遍历所有 content_view 节点
  76.     var 位置 = 0;
  77.     while (true) {
  78.         var cvIdx = 后面.indexOf('id/content_view"', 位置);
  79.         if (cvIdx === -1) break;

  80.         // 从 content_view 起始位置截取一段,找它内部第一个有非空 text 的 TextView
  81.         var 段 = 后面.substring(cvIdx);
  82.         // 找到 content_view 节点开始标签的结束位置 ">"
  83.         var 标签结束 = 段.indexOf(">");
  84.         if (标签结束 === -1) break;
  85.         var 子段 = 段.substring(标签结束 + 1);

  86.         // 在子段中查找第一个有非空 text 的 TextView 节点
  87.         var 文本匹配 = 子段.match(/<node[^>]*?text="([^"]+)"[^>]*?class="android\.widget\.TextView"[^>]*?\/?>/);
  88.         if (!文本匹配) {
  89.             // 备选顺序:先 class 再 text
  90.             文本匹配 = 子段.match(/<node[^>]*?class="android\.widget\.TextView"[^>]*?text="([^"]+)"[^>]*?\/?>/);
  91.         }

  92.         if (文本匹配 && 文本匹配[1]) {
  93.             var 原始文本 = 文本匹配[1];
  94.             var 解码文本 = 解码HTML实体(原始文本);
  95.             if (严格过滤) {
  96.                 // 严格模式:排除按钮文案(复制、分享等),AI回答特征:含换行 或 长度>30
  97.                 if (解码文本.indexOf("\n") !== -1 || 字符串长度(解码文本) > 30) {
  98.                     回答列表.push(解码文本);
  99.                 }
  100.             } else {
  101.                 // 宽松模式:只要有非空文本就算,用于灵敏检测新回答出现
  102.                 if (字符串长度(解码文本) > 0) {
  103.                     回答列表.push(解码文本);
  104.                 }
  105.             }
  106.         }

  107.         位置 = cvIdx + 30;
  108.     }

  109.     return 回答列表;
  110. }

  111. // 查找输入框中心坐标(resource-id 含 input_text 的 EditText)
  112. function 查找输入框中心(xml) {
  113.     var xmlStr = "" + xml;
  114.     var idx = xmlStr.indexOf('id/input_text"');
  115.     if (idx === -1) return null;

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

  119.     var x1 = parseInt(m[1]);
  120.     var y1 = parseInt(m[2]);
  121.     var x2 = parseInt(m[3]);
  122.     var y2 = parseInt(m[4]);
  123.     return {
  124.         x: (x1 + x2) / 2,
  125.         y: (y1 + y2) / 2
  126.     };
  127. }

  128. // 查找发送按钮坐标
  129. // 豆包输入框右侧的 action_speak 节点,输入文字后会变成发送按钮
  130. // 也查找文字"发送"或 resource-id 含 action_send 的节点
  131. function 查找发送按钮中心(xml) {
  132.     var xmlStr = "" + xml;

  133.     // 1. 优先查找文字"发送"
  134.     var sendTextIdx = xmlStr.indexOf('text="发送"');
  135.     if (sendTextIdx !== -1) {
  136.         var 段 = xmlStr.substring(sendTextIdx);
  137.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  138.         if (m) {
  139.             return {
  140.                 x: (parseInt(m[1]) + parseInt(m[3])) / 2,
  141.                 y: (parseInt(m[2]) + parseInt(m[4])) / 2
  142.             };
  143.         }
  144.     }

  145.     // 2. 查找 resource-id 含 action_send
  146.     var sendIdIdx = xmlStr.indexOf('id/action_send"');
  147.     if (sendIdIdx !== -1) {
  148.         var 段2 = xmlStr.substring(sendIdIdx);
  149.         var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  150.         if (m2) {
  151.             return {
  152.                 x: (parseInt(m2[1]) + parseInt(m2[3])) / 2,
  153.                 y: (parseInt(m2[2]) + parseInt(m2[4])) / 2
  154.             };
  155.         }
  156.     }

  157.     // 3. 兜底:使用 action_speak 节点坐标(输入文字后该按钮变为发送功能)
  158.     var speakIdx = xmlStr.indexOf('id/action_speak"');
  159.     if (speakIdx !== -1) {
  160.         var 段3 = xmlStr.substring(speakIdx);
  161.         var m3 = 段3.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  162.         if (m3) {
  163.             return {
  164.                 x: (parseInt(m3[1]) + parseInt(m3[3])) / 2,
  165.                 y: (parseInt(m3[2]) + parseInt(m3[4])) / 2
  166.             };
  167.         }
  168.     }

  169.     return null;
  170. }

  171. // 粘贴文本到当前焦点输入框(剪贴板法,兼容中文)
  172. function 粘贴文本(文本) {
  173.     try {
  174.         Clipboard.copy("" + 文本);
  175.     } catch (e) {
  176.         print.log("⚠ Clipboard.copy 失败:" + e.message);
  177.     }
  178.     sleep.millisecond(毫秒 = 300);

  179.     // 双保险:通过 shell 写剪贴板
  180.     try {
  181.         agent.shell("service call clipboard 3 i32 1 s16 '" + 文本 + "' i32 0");
  182.     } catch (e2) {
  183.         // 忽略错误
  184.     }
  185.     sleep.millisecond(毫秒 = 300);

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

  191. // 查找并点击AI回答底部的展开按钮(向下箭头)
  192. // 豆包长回答会折叠显示,需要点击展开箭头才能看到完整内容
  193. // 从XML中动态定位,不依赖硬编码坐标
  194. function 查找并点击展开按钮(xml) {
  195.     var xmlStr = "" + xml;
  196.    
  197.     // 1. 查找 content-desc 含"展开"或"更多"的按钮
  198.     var expandIdx = xmlStr.indexOf('content-desc="展开"');
  199.     if (expandIdx === -1) {
  200.         expandIdx = xmlStr.indexOf('content-desc="更多"');
  201.     }
  202.     if (expandIdx === -1) {
  203.         expandIdx = xmlStr.indexOf('content-desc="收起"');
  204.     }
  205.    
  206.     if (expandIdx !== -1) {
  207.         var 段 = xmlStr.substring(expandIdx);
  208.         var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  209.         if (m) {
  210.             var x = (parseInt(m[1]) + parseInt(m[3])) / 2;
  211.             var y = (parseInt(m[2]) + parseInt(m[4])) / 2;
  212.             agent.click(x, y);
  213.             print.log("✓ 已点击展开按钮(content-desc),坐标(" + Math.round(x) + "," + Math.round(y) + ")");
  214.             sleep.second(秒 = 1);
  215.             return true;
  216.         }
  217.     }

  218.     // 2. 查找文本"展开"或"更多"的按钮
  219.     var textExpandIdx = xmlStr.indexOf('text="展开"');
  220.     if (textExpandIdx === -1) {
  221.         textExpandIdx = xmlStr.indexOf('text="更多"');
  222.     }
  223.     if (textExpandIdx !== -1) {
  224.         var 段2 = xmlStr.substring(textExpandIdx);
  225.         var m2 = 段2.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  226.         if (m2) {
  227.             var x2 = (parseInt(m2[1]) + parseInt(m2[3])) / 2;
  228.             var y2 = (parseInt(m2[2]) + parseInt(m2[4])) / 2;
  229.             agent.click(x2, y2);
  230.             print.log("✓ 已点击展开按钮(文本匹配),坐标(" + Math.round(x2) + "," + Math.round(y2) + ")");
  231.             sleep.second(秒 = 1);
  232.             return true;
  233.         }
  234.     }

  235.     // 3. 兜底:从XML解析最后一个 content_view 的底部中心位置(展开箭头通常在回答底部中间)
  236.     var lastCVIdx = xmlStr.lastIndexOf('id/content_view"');
  237.     if (lastCVIdx !== -1) {
  238.         var cv段 = xmlStr.substring(lastCVIdx);
  239.         var cvM = cv段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  240.         if (cvM) {
  241.             var cvX1 = parseInt(cvM[1]);
  242.             var cvY1 = parseInt(cvM[2]);
  243.             var cvX2 = parseInt(cvM[3]);
  244.             var cvY2 = parseInt(cvM[4]);
  245.             // 点击 content_view 底部中间位置(展开箭头通常在这里)
  246.             var centerX = (cvX1 + cvX2) / 2;
  247.             var bottomY = cvY2 - 50; // 稍微往上一点,避开边缘
  248.             agent.click(centerX, bottomY);
  249.             print.log("✓ 已点击content_view底部(兜底展开),坐标(" + Math.round(centerX) + "," + Math.round(bottomY) + ")");
  250.             sleep.second(秒 = 1);
  251.             return true;
  252.         }
  253.     }

  254.     // 4. 最终兜底:使用屏幕百分比坐标(仅作为最后备选)
  255.     var pctX = 屏幕宽 / 2;
  256.     var pctY = 屏幕高 * 0.85;
  257.     agent.click(pctX, pctY);
  258.     print.log("✓ 已点击屏幕底部(最终兜底),坐标(" + Math.round(pctX) + "," + Math.round(pctY) + ")");
  259.     sleep.second(秒 = 1);
  260.     return true;
  261. }

  262. // 从XML解析 message_list 的边界,然后在其中滑动到底部
  263. // 不依赖硬编码坐标,换手机也能运行
  264. function 滑动消息列表到底部(xml) {
  265.     var xmlStr = "" + xml;
  266.     var listIdx = xmlStr.indexOf('id/message_list"');
  267.     if (listIdx === -1) {
  268.         print.log("⚠ 未找到message_list,使用屏幕百分比滑动");
  269.         agent.swip(屏幕宽 / 2, 屏幕高 * 0.3, 屏幕宽 / 2, 屏幕高 * 0.8, 500);
  270.         return;
  271.     }

  272.     var 段 = xmlStr.substring(listIdx);
  273.     var m = 段.match(/bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/);
  274.     if (!m) {
  275.         print.log("⚠ 未找到message_list边界,使用屏幕百分比滑动");
  276.         agent.swip(屏幕宽 / 2, 屏幕高 * 0.3, 屏幕宽 / 2, 屏幕高 * 0.8, 500);
  277.         return;
  278.     }

  279.     var x1 = parseInt(m[1]);
  280.     var y1 = parseInt(m[2]);
  281.     var x2 = parseInt(m[3]);
  282.     var y2 = parseInt(m[4]);

  283.     // 在 message_list 区域内滑动:从上半部分滑到下半部分
  284.     var startX = (x1 + x2) / 2;
  285.     var startY = y1 + (y2 - y1) * 0.2; // 区域上方20%位置
  286.     var endX = startX;
  287.     var endY = y1 + (y2 - y1) * 0.8;   // 区域下方20%位置

  288.     agent.swip(startX, startY, endX, endY, 500);
  289.     print.log("✓ 已在message_list内滑动,区域[" + x1 + "," + y1 + "][" + x2 + "," + y2 + "]");
  290. }
  291. // 等待AI回答完成
  292. // 逻辑:
  293. //   阶段1:宽松检测 - 等待最后一条回答文本变化(新回答出现)
  294. //   阶段2:检测到新回答后,先点击展开按钮,再等待回答输出等待秒,然后直接返回
  295. //   超时兜底:若整体超时但能采到非空文本,也返回当前内容
  296. // 参数:发送前的最后一条AI回答文本(用于对比检测新回答)
  297. // 返回:新回答的文本内容
  298. function 等待AI回答完成(发送前的最后文本) {
  299.     var 已耗时 = 0;
  300.     var 检查间隔秒 = 2;
  301.     var 已检测到新回答 = false;
  302.     var 检测到的时间点 = 0;
  303.     var 已点击展开按钮 = false;

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

  307.         var xml = 获取UI();

  308.         if (!已检测到新回答) {
  309.             // 阶段1:宽松模式检测新回答是否出现
  310.             var 宽松列表 = 采集AI回答列表(xml, false);
  311.             if (宽松列表.length === 0) {
  312.                 continue;
  313.             }
  314.             var 当前最后文本 = 宽松列表[宽松列表.length - 1];
  315.             if (当前最后文本 !== 发送前的最后文本 && 字符串长度(当前最后文本) > 0) {
  316.                 print.log("✓ 检测到新回答出现(" + 已耗时 + "秒),等待" + 回答输出等待秒 + "秒后采集");
  317.                 已检测到新回答 = true;
  318.                 检测到的时间点 = 已耗时;
  319.             }
  320.         } else {
  321.             // 阶段2:已检测到新回答
  322.             var 已等待 = 已耗时 - 检测到的时间点;
  323.             
  324.             // 先点击展开按钮(只点击一次)
  325.             if (!已点击展开按钮 && 已等待 >= 2) {
  326.                 查找并点击展开按钮(xml);
  327.                 已点击展开按钮 = true;
  328.             }
  329.             
  330.             // 再等回答输出等待秒后直接返回
  331.             if (已等待 >= 回答输出等待秒) {
  332.                 var 严格列表 = 采集AI回答列表(xml, true);
  333.                 if (严格列表.length > 0) {
  334.                     var 最终回答 = 严格列表[严格列表.length - 1];
  335.                     if (最终回答 !== 发送前的最后文本 && 字符串长度(最终回答) > 0) {
  336.                         print.log("✓ 已等待" + 已等待 + "秒,返回采集结果");
  337.                         return 最终回答;
  338.                     }
  339.                 }
  340.                 // 严格模式没采到,用宽松模式
  341.                 var 宽松列表2 = 采集AI回答列表(xml, false);
  342.                 if (宽松列表2.length > 0) {
  343.                     var 最终回答2 = 宽松列表2[宽松列表2.length - 1];
  344.                     if (最终回答2 !== 发送前的最后文本 && 字符串长度(最终回答2) > 5) {
  345.                         print.log("✓ 已等待" + 已等待 + "秒(宽松模式),返回采集结果");
  346.                         return 最终回答2;
  347.                     }
  348.                 }
  349.             }
  350.         }
  351.     }

  352.     // 超时兜底:尽量返回当前能采集到的最后一条回答
  353.     print.log("⚠ 等待AI回答超时(" + 等待回答超时秒 + "秒),尝试返回当前内容");
  354.     var xml = 获取UI();
  355.     var 兜底列表 = 采集AI回答列表(xml, true);
  356.     if (兜底列表.length > 0) {
  357.         var 兜底文本 = 兜底列表[兜底列表.length - 1];
  358.         if (兜底文本 !== 发送前的最后文本) {
  359.             print.log("✓ 超时兜底:返回当前采集到的回答");
  360.             return 兜底文本;
  361.         }
  362.     }
  363.     var 兜底宽松 = 采集AI回答列表(xml, false);
  364.     if (兜底宽松.length > 0) {
  365.         var 兜底文本2 = 兜底宽松[兜底宽松.length - 1];
  366.         if (兜底文本2 !== 发送前的最后文本 && 字符串长度(兜底文本2) > 5) {
  367.             print.log("✓ 超时兜底(宽松):返回当前采集到的回答");
  368.             return 兜底文本2;
  369.         }
  370.     }
  371.     return null;
  372. }

  373. // 获取当前页面最后一条AI回答文本(用于发送前记录基线)
  374. function 获取当前最后AI回答(xml) {
  375.     var 回答列表 = 采集AI回答列表(xml);
  376.     if (回答列表.length === 0) return "";
  377.     return 回答列表[回答列表.length - 1];
  378. }

  379. // 格式化对话内容输出
  380. function 格式化对话(对话列表) {
  381.     var 输出 = "";
  382.     输出 += "========================================\n";
  383.     输出 += "豆包对话采集记录\n";
  384.     输出 += "采集时间:" + new Date().toString() + "\n";
  385.     输出 += "对话轮数:" + 对话列表.length + "\n";
  386.     输出 += "========================================\n\n";

  387.     for (var i = 0; i < 对话列表.length; i++) {
  388.         var 对话 = 对话列表[i];
  389.         if (对话.角色 === "用户") {
  390.             输出 += "【用户提问 " + (i + 1) + "】\n";
  391.         } else {
  392.             输出 += "【豆包回答 " + (i + 1) + "】\n";
  393.         }
  394.         输出 += 对话.内容 + "\n";
  395.         输出 += "----------------------------------------\n\n";
  396.     }

  397.     输出 += "\n===== 采集结束 =====\n";
  398.     return 输出;
  399. }

  400. // 写入文件(UTF-8 BOM格式,兼容Windows记事本)
  401. function 写入文件(文件路径, 内容) {
  402.     try {
  403.         var fos = new java.io.FileOutputStream(文件路径);
  404.         var osw = new java.io.OutputStreamWriter(fos, "UTF-8");
  405.         osw.write('\ufeff');
  406.         osw.write(内容);
  407.         osw.flush();
  408.         osw.close();
  409.         fos.close();
  410.         print.log("✓ 已写入文件(UTF-8 BOM):" + 文件路径);
  411.         
  412.         var catResult = agent.shell("cat " + 文件路径 + " | head -3");
  413.         print.log("✓ cat验证结果:" + catResult);
  414.         
  415.         var fileSize = agent.shell("ls -la " + 文件路径);
  416.         print.log("✓ 文件信息:" + fileSize);
  417.         
  418.         return true;
  419.     } catch (e) {
  420.         print.log("⚠ UTF-8 BOM写入异常:" + e.message);
  421.     }

  422.     try {
  423.         var fos2 = new java.io.FileOutputStream(文件路径);
  424.         fos2.write(239);
  425.         fos2.write(187);
  426.         fos2.write(191);
  427.         fos2.write(内容.getBytes("UTF-8"));
  428.         fos2.close();
  429.         print.log("✓ 已写入文件(字节写入BOM):" + 文件路径);
  430.         return true;
  431.     } catch (e2) {
  432.         print.log("⚠ 字节写入异常:" + e2.message);
  433.     }

  434.     print.log("✗ 写入文件失败:" + 文件路径);
  435.     return false;
  436. }

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

  438. // 步骤1:启动豆包APP
  439. print.log("\n========== 步骤1:启动豆包APP ==========");
  440. try {
  441.     app.openApp(豆包包名);
  442.     print.log("✓ 已启动豆包");
  443. } catch (e) {
  444.     print.log("⚠ 启动失败:" + e.message);
  445. }
  446. sleep.second(秒 = 5);

  447. // 步骤2:确认进入对话页面
  448. print.log("\n========== 步骤2:确认进入对话页面 ==========");
  449. var xml = 获取UI();
  450. if (xml.indexOf("message_list") === -1) {
  451.     print.log("⚠ 当前页面可能不是豆包对话页,再次等待");
  452.     sleep.second(秒 = 3);
  453.     xml = 获取UI();
  454. }

  455. if (xml.indexOf("message_list") !== -1) {
  456.     print.log("✓ 已进入豆包对话页面");
  457. } else {
  458.     print.log("⚠ 未检测到消息列表,继续尝试");
  459. }

  460. // 步骤3:循环发送问题并采集回答
  461. print.log("\n========== 步骤3:循环发送问题并采集回答 ==========");

  462. // 完整对话列表(包含用户问题和AI回答)
  463. var 完整对话 = [];

  464. // 先采集当前页面已有的AI回答
  465. var 已有回答 = 采集AI回答列表(xml);
  466. print.log("✓ 当前页面已有AI回答数量:" + 已有回答.length);
  467. for (var i = 0; i < 已有回答.length; i++) {
  468.     完整对话.push({
  469.         角色: "AI",
  470.         内容: 已有回答[i]
  471.     });
  472. }

  473. // 开始发送问题
  474. for (var q = 0; q < 要发送的问题列表.length; q++) {
  475.     var 当前问题 = 要发送的问题列表[q];
  476.     print.log("\n---- 第 " + (q + 1) + " / " + 要发送的问题列表.length + " 个问题 ----");
  477.     print.log("问题:" + 当前问题);

  478.     // 3.1 重新获取UI,定位输入框
  479.     xml = 获取UI();
  480.     var 输入框 = 查找输入框中心(xml);
  481.     if (!输入框) {
  482.         print.log("⚠ 未找到输入框,跳过此问题");
  483.         sleep.second(秒 = 问题间隔秒);
  484.         continue;
  485.     }

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

  488.     // 3.3 点击输入框获取焦点
  489.     agent.click(输入框.x, 输入框.y);
  490.     sleep.second(秒 = 1);

  491.     // 3.4 粘贴问题文本
  492.     粘贴文本(当前问题);

  493.     // 3.5 重新获取UI,查找发送按钮
  494.     xml = 获取UI();
  495.     var 发送按钮 = 查找发送按钮中心(xml);

  496.     if (发送按钮) {
  497.         agent.click(发送按钮.x, 发送按钮.y);
  498.         print.log("✓ 已点击发送按钮");
  499.     } else {
  500.         // 兜底:按回车键发送
  501.         agent.shell("input keyevent 66");
  502.         print.log("⚠ 未找到发送按钮,已尝试按回车发送");
  503.     }

  504.     // 3.6 记录用户问题
  505.     完整对话.push({
  506.         角色: "用户",
  507.         内容: 当前问题
  508.     });

  509.     // 3.7 等待AI回答完成(基于"最后一条回答文本变化"判断,不依赖数量递增)
  510.     print.log("等待AI回答,发送前最后文本长度:" + 字符串长度(发送前最后文本));

  511.     var 新回答文本 = 等待AI回答完成(发送前最后文本);
  512.     if (新回答文本 && 字符串长度(新回答文本) > 0) {
  513.         完整对话.push({
  514.             角色: "AI",
  515.             内容: 新回答文本
  516.         });
  517.         print.log("✓ 采集到新回答,当前总对话条数:" + 完整对话.length);
  518.         print.log("--- 采集内容开始 ---");
  519.         print.log(新回答文本);
  520.         print.log("--- 采集内容结束 ---");
  521.     } else {
  522.         print.log("⚠ 未能采集到新回答");
  523.     }

  524.     sleep.second(秒 = 问题间隔秒);
  525. }

  526. // 步骤4:保存对话到文件
  527. print.log("\n========== 步骤4:保存对话到文件 ==========");
  528. var 输出内容 = 格式化对话(完整对话);
  529. var 写入成功 = 写入文件(输出文件路径, 输出内容);

  530. if (写入成功) {
  531.     print.log("✓ 对话已保存到:" + 输出文件路径);
  532.     print.log("✓ 总对话条数:" + 完整对话.length);
  533. } else {
  534.     print.log("✗ 保存失败,请检查存储权限");
  535. }

  536. // 步骤5:打印全部采集到的对话内容
  537. print.log("\n========== 全部采集内容 ==========");
  538. print.log(输出内容);
  539. print.log("========== 内容结束 ==========");

  540. print.log("\n===== 豆包对话采集流程结束 =====");
复制代码



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三大主流论坛,有手机验证码收件,邮件收发的功能,支持验证码识别,注册问题识别,多线程任务,自动上传头像,自动激活注册邮件,兼容防注册插件,本站软件原创正版,更新效率最快的原创软件。 『网络推广软件』『自动发帖软件』『 自动发帖