 | |  |  | 代理模式简书自动流程
- // AIWROK 完整自动化流程:启动简书 → 我的 → 写文章 → 输入内容 → 发布
- // 代理模式简书自动流程
- print.log("===== 简书写文章流程启动 =====");
- print.time();
- // ========== 工具函数 ==========
- function 执行Shell(命令) {
- var 结果 = agent.shell(命令);
- if (!结果) return "";
-
- var 结果字符串 = "";
- if (typeof 结果 === "string") {
- 结果字符串 = 结果;
- } else if (结果.toString) {
- 结果字符串 = 结果.toString();
- } else {
- 结果字符串 = "" + 结果;
- }
-
- var startIdx = -1;
- if (typeof 结果字符串.indexOf === "function") {
- startIdx = 结果字符串.indexOf("successMsg:");
- }
-
- if (startIdx !== -1) {
- var afterSuccess = 结果字符串.substring(startIdx + 11);
- var errorIdx = afterSuccess.indexOf(",errorMsg:");
- if (errorIdx !== -1) {
- var content = afterSuccess.substring(0, errorIdx);
- var endMarker = content.indexOf("UI hierchary dumped to:");
- if (endMarker !== -1) {
- content = content.substring(0, endMarker);
- }
- return "" + content.trim();
- }
- return "" + afterSuccess.trim();
- }
-
- return "" + 结果字符串;
- }
- function 获取UI() {
- var 临时文件 = "/sdcard/ui_dump.xml";
- agent.shell("uiautomator dump --compressed " + 临时文件 + " 2>/dev/null");
- var 结果 = agent.shell("cat " + 临时文件);
-
- if (!结果) return "";
-
- var 结果字符串 = "";
- if (typeof 结果 === "string") {
- 结果字符串 = 结果;
- } else if (结果.toString) {
- 结果字符串 = 结果.toString();
- } else {
- 结果字符串 = "" + 结果;
- }
-
- var startIdx = -1;
- if (typeof 结果字符串.indexOf === "function") {
- startIdx = 结果字符串.indexOf("successMsg:");
- }
-
- var content = "";
- if (startIdx !== -1) {
- var afterSuccess = 结果字符串.substring(startIdx + 11);
- var errorIdx = afterSuccess.indexOf(",errorMsg:");
- if (errorIdx !== -1) {
- content = afterSuccess.substring(0, errorIdx);
- var endMarker = content.indexOf("UI hierchary dumped to:");
- if (endMarker !== -1) {
- content = content.substring(0, endMarker);
- }
- } else {
- content = afterSuccess;
- }
- content = content.trim();
- } else {
- content = 结果字符串;
- }
-
- return "" + content;
- }
- function 字符串长度(str) {
- if (typeof str.length === "function") {
- return str.length();
- }
- return str.length || 0;
- }
- function 获取当前包名() {
- var uiXml = 获取UI();
- var m = uiXml.match(/package="([^"]+)"/);
- if (m) {
- return "" + m[1];
- }
- return "";
- }
- function 查找包含文字的节点(xml, 关键词) {
- var 节点列表 = [];
- for (var i = 0; i < 关键词.length; i++) {
- var 词 = 关键词[i];
- var pos = 0;
- while (true) {
- pos = xml.indexOf('text="' + 词 + '"', pos);
- if (pos < 0) break;
- var boundsStart = xml.indexOf('bounds="', pos);
- if (boundsStart >= 0) {
- var boundsEnd = xml.indexOf('"', boundsStart + 8);
- if (boundsEnd >= 0) {
- var boundsStr = xml.substring(boundsStart + 8, boundsEnd);
- var m = boundsStr.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);
- if (m) {
- var node = {
- text: 词,
- x1: parseInt(m[1]),
- y1: parseInt(m[2]),
- x2: parseInt(m[3]),
- y2: parseInt(m[4]),
- cx: (parseInt(m[1]) + parseInt(m[3])) / 2,
- cy: (parseInt(m[2]) + parseInt(m[4])) / 2
- };
- 节点列表.push(node);
- }
- }
- }
- pos += 字符串长度(词);
- }
- }
- return 节点列表;
- }
- function 查找包含资源ID的节点(xml, 资源ID关键词) {
- var 节点列表 = [];
- for (var i = 0; i < 资源ID关键词.length; i++) {
- var 关键词 = 资源ID关键词[i];
- var pos = 0;
- while (true) {
- pos = xml.indexOf('resource-id="', pos);
- if (pos < 0) break;
- var idEnd = xml.indexOf('"', pos + 13);
- if (idEnd >= 0) {
- var resourceId = xml.substring(pos + 13, idEnd);
- if (resourceId.indexOf(关键词) !== -1) {
- var boundsStart = xml.indexOf('bounds="', pos);
- if (boundsStart >= 0) {
- var boundsEnd = xml.indexOf('"', boundsStart + 8);
- if (boundsEnd >= 0) {
- var boundsStr = xml.substring(boundsStart + 8, boundsEnd);
- var m = boundsStr.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);
- if (m) {
- var node = {
- resourceId: resourceId,
- x1: parseInt(m[1]),
- y1: parseInt(m[2]),
- x2: parseInt(m[3]),
- y2: parseInt(m[4]),
- cx: (parseInt(m[1]) + parseInt(m[3])) / 2,
- cy: (parseInt(m[2]) + parseInt(m[4])) / 2
- };
- 节点列表.push(node);
- }
- }
- }
- }
- }
- pos = idEnd + 1;
- }
- }
- return 节点列表;
- }
- function 输入文本(文本, 点击X, 点击Y) {
- if (!点击X) 点击X = 0.2;
- if (!点击Y) 点击Y = 0.2;
-
- agent.clickPercent(点击X, 点击Y);
- sleep.millisecond(毫秒 = 500);
-
- agent.shell("service call clipboard 4 i32 1 s16 '" + 文本 + "' i32 0");
- sleep.millisecond(毫秒 = 300);
- agent.shell("service call clipboard 3 i32 1 s16 '" + 文本 + "' i32 0");
- sleep.millisecond(毫秒 = 300);
-
- try {
- Clipboard.copy(文本);
- sleep.millisecond(毫秒 = 300);
- } catch (e) {}
-
- print.log("✓ 剪贴板已设置内容");
-
- agent.shell("input keyevent 279");
- sleep.second(秒 = 1);
- }
- function 查找WebView节点(xml) {
- var 节点列表 = [];
- var pos = 0;
- while (true) {
- pos = xml.indexOf('class="android.webkit.WebView"', pos);
- if (pos < 0) break;
- var boundsStart = xml.indexOf('bounds="', pos);
- if (boundsStart >= 0) {
- var boundsEnd = xml.indexOf('"', boundsStart + 8);
- if (boundsEnd >= 0) {
- var boundsStr = xml.substring(boundsStart + 8, boundsEnd);
- var m = boundsStr.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);
- if (m) {
- var node = {
- x1: parseInt(m[1]),
- y1: parseInt(m[2]),
- x2: parseInt(m[3]),
- y2: parseInt(m[4]),
- cx: (parseInt(m[1]) + parseInt(m[3])) / 2,
- cy: (parseInt(m[2]) + parseInt(m[4])) / 2
- };
- 节点列表.push(node);
- }
- }
- }
- pos += 25;
- }
- return 节点列表;
- }
- // ========== 配置区 ==========
- var APP包名 = "com.jianshu.haruki";
- var 循环次数 = 3;
- var 当前循环 = 0;
- var 文章标题 = "AI技术发展趋势";
- var 文章正文 = "人工智能技术正在飞速发展,改变着我们生活的方方面面。从机器学习到深度学习,从自然语言处理到计算机视觉,AI的应用场景越来越广泛。未来,AI将在更多领域发挥重要作用,推动社会进步和创新发展。";
- // ========== 获取设备信息 (agent模式) ==========
- var wm结果 = 执行Shell("wm size");
- var m = wm结果.match(/(\d+)x(\d+)/);
- var 屏幕宽 = m ? parseInt(m[1]) : 1080;
- var 屏幕高 = m ? parseInt(m[2]) : 2400;
- print.log("屏幕尺寸:" + 屏幕宽 + " x " + 屏幕高);
- print.log("代理状态:" + (agent.isOpen() ? "已开启" : "未开启"));
- print.log("目标APP:" + APP包名 + " (简书)");
- // ========================================
- // 主循环开始
- // ========================================
- for (当前循环 = 1; 当前循环 <= 循环次数; 当前循环++) {
- print.log("\n======================================");
- print.log("===== 第 " + 当前循环 + " / " + 循环次数 + " 次循环 =====");
- print.log("======================================");
- // ========================================
- // 步骤1:启动简书APP
- // ========================================
- print.log("\n========== 步骤1:启动简书APP ==========");
- var 启动成功 = false;
- var 启动尝试次数 = 0;
- var 最大启动尝试 = 3;
- while (!启动成功 && 启动尝试次数 < 最大启动尝试) {
- 启动尝试次数++;
- try {
- agent.shell("monkey -p " + APP包名 + " -c android.intent.category.LAUNCHER 1");
- print.log("✓ 第" + 启动尝试次数 + "次尝试启动简书");
- } catch (e) {
- print.log("⚠ 第" + 启动尝试次数 + "次启动失败:" + e.message);
- }
-
- sleep.second(秒 = 5);
-
- var 当前页面包名 = 获取当前包名();
- print.log("当前页面包名:" + 当前页面包名);
-
- if (当前页面包名 === APP包名) {
- 启动成功 = true;
- print.log("✓ APP启动成功");
- } else {
- print.log("⚠ 当前页面不是简书,准备重新启动");
- }
- }
- if (!启动成功) {
- print.log("✗ 多次尝试启动失败,跳过本次循环");
- continue;
- }
- // ========================================
- // 步骤2:设置ADB输入法(支持中文输入)
- // ========================================
- print.log("\n========== 步骤2:设置ADB输入法 ==========");
- try {
- var 当前输入法 = 执行Shell("settings get secure default_input_method");
- print.log("当前默认输入法:" + 当前输入法);
-
- var adbKeyboard = "com.android.adbkeyboard/.AdbIME";
- if (当前输入法.indexOf("adbkeyboard") === -1) {
- print.log("当前不是ADB输入法,尝试切换");
- agent.shell("ime enable " + adbKeyboard);
- sleep.millisecond(毫秒 = 300);
- agent.shell("ime set " + adbKeyboard);
- sleep.millisecond(毫秒 = 500);
- print.log("✓ 已切换到ADB输入法");
- } else {
- print.log("✓ 当前已是ADB输入法");
- }
- } catch (e) {
- print.log("⚠ 设置ADB输入法失败:" + e.message);
- print.log("提示:请手动安装ADB Keyboard并设置为默认输入法");
- }
- // ========================================
- // 步骤3:查找并点击写文章按钮(悬浮铅笔按钮)
- // ========================================
- print.log("\n========== 步骤3:查找写文章按钮(悬浮铅笔按钮)==========");
- function 查找悬浮按钮(xml) {
- var 节点列表 = [];
-
- var fabClasses = [
- 'class="android.support.design.widget.FloatingActionButton"',
- 'class="com.google.android.material.floatingactionbutton.FloatingActionButton"',
- 'class="android.widget.ImageView"'
- ];
-
- for (var c = 0; c < fabClasses.length; c++) {
- var pos = 0;
- while (true) {
- pos = xml.indexOf(fabClasses[c], pos);
- if (pos < 0) break;
- var boundsStart = xml.indexOf('bounds="', pos);
- if (boundsStart >= 0) {
- var boundsEnd = xml.indexOf('"', boundsStart + 8);
- if (boundsEnd >= 0) {
- var boundsStr = xml.substring(boundsStart + 8, boundsEnd);
- var m = boundsStr.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);
- if (m) {
- var x1 = parseInt(m[1]);
- var y1 = parseInt(m[2]);
- var x2 = parseInt(m[3]);
- var y2 = parseInt(m[4]);
- var cx = (x1 + x2) / 2;
- var cy = (y1 + y2) / 2;
- var width = x2 - x1;
- var height = y2 - y1;
- if (cx > 屏幕宽 * 0.6 && cy > 屏幕高 * 0.75 && width > 50 && height > 50) {
- var node = {
- x1: x1,
- y1: y1,
- x2: x2,
- y2: y2,
- cx: cx,
- cy: cy
- };
- 节点列表.push(node);
- }
- }
- }
- }
- pos += fabClasses[c].length;
- }
- }
-
- return 节点列表;
- }
- var 找到写文章按钮 = false;
- var 尝试次数3 = 0;
- var 最大尝试次数3 = 3;
- while (!找到写文章按钮 && 尝试次数3 < 最大尝试次数3) {
- 尝试次数3++;
- var 首页UI = 获取UI();
- var xml长度3 = 字符串长度(首页UI);
-
- print.log("第 " + 尝试次数3 + " 次尝试获取首页UI,长度:" + xml长度3);
-
- if (xml长度3 < 100) {
- print.log("UI数据过短,重试");
- sleep.second(秒 = 1);
- continue;
- }
-
- var 悬浮按钮列表 = 查找悬浮按钮(首页UI);
-
- if (悬浮按钮列表.length > 0) {
- var 写文章按钮 = 悬浮按钮列表[0];
- var 写文章X = 写文章按钮.cx / 屏幕宽;
- var 写文章Y = 写文章按钮.cy / 屏幕高;
- agent.clickPercent(写文章X, 写文章Y);
- print.log("✓ 已点击悬浮铅笔按钮,百分比坐标:(" + 写文章X.toFixed(4) + ", " + 写文章Y.toFixed(4) + ")");
- 找到写文章按钮 = true;
- } else {
- var 编辑资源ID节点 = 查找包含资源ID的节点(首页UI, ["write", "create", "edit", "publish", "fab"]);
-
- if (编辑资源ID节点.length > 0) {
- var 编辑按钮 = 编辑资源ID节点[0];
- var 编辑X = (编辑按钮.x1 + 编辑按钮.x2) / 2 / 屏幕宽;
- var 编辑Y = (编辑按钮.y1 + 编辑按钮.y2) / 2 / 屏幕高;
- agent.clickPercent(编辑X, 编辑Y);
- print.log("✓ 已点击写文章按钮(通过资源ID),百分比坐标:(" + 编辑X.toFixed(4) + ", " + 编辑Y.toFixed(4) + ")");
- 找到写文章按钮 = true;
- } else {
- var 写文章节点 = 查找包含文字的节点(首页UI, ["写文章", "创作", "编辑", "写", "发布"]);
-
- if (写文章节点.length > 0) {
- var 写文章按钮 = 写文章节点[0];
- var 写文章X = (写文章按钮.x1 + 写文章按钮.x2) / 2 / 屏幕宽;
- var 写文章Y = (写文章按钮.y1 + 写文章按钮.y2) / 2 / 屏幕高;
- agent.clickPercent(写文章X, 写文章Y);
- print.log("✓ 已点击「" + 写文章按钮.text + "」,百分比坐标:(" + 写文章X.toFixed(4) + ", " + 写文章Y.toFixed(4) + ")");
- 找到写文章按钮 = true;
- } else {
- print.log("✓ 使用默认坐标点击右下角悬浮按钮");
- agent.clickPercent(0.875, 0.91);
- 找到写文章按钮 = true;
- }
- }
- }
- }
- if (!找到写文章按钮) {
- print.log("✗ 多次尝试未找到写文章按钮,跳过本次循环");
- continue;
- }
- sleep.second(秒 = 3);
- // ========================================
- // 步骤4:输入文章标题(WebView编辑器)
- // ========================================
- print.log("\n========== 步骤4:输入文章标题 ==========");
- var 标题输入成功 = false;
- var 尝试次数4 = 0;
- var 最大尝试次数4 = 3;
- while (!标题输入成功 && 尝试次数4 < 最大尝试次数4) {
- 尝试次数4++;
- var 编辑页面UI = 获取UI();
- var xml长度4 = 字符串长度(编辑页面UI);
-
- print.log("第 " + 尝试次数4 + " 次尝试获取编辑页面UI,长度:" + xml长度4);
-
- if (xml长度4 < 100) {
- print.log("UI数据过短,重试");
- sleep.second(秒 = 1);
- continue;
- }
-
- var webView节点 = 查找WebView节点(编辑页面UI);
-
- if (webView节点.length > 0) {
- var webView = webView节点[0];
- var 点击X = (webView.x1 + webView.x2) / 2 / 屏幕宽;
- var 点击Y = (webView.y1 + 200) / 屏幕高;
- print.log("✓ 准备在WebView编辑区域输入标题,百分比坐标:(" + 点击X.toFixed(4) + ", " + 点击Y.toFixed(4) + ")");
-
- 输入文本(文章标题, 点击X, 点击Y);
- sleep.millisecond(毫秒 = 500);
- agent.shell("input keyevent 66");
- sleep.millisecond(毫秒 = 300);
- print.log("✓ 标题输入完成");
- 标题输入成功 = true;
- } else {
- print.log("⚠ 未找到WebView节点,直接点击编辑区域");
- 输入文本(文章标题, 0.2, 0.6);
- sleep.millisecond(毫秒 = 500);
- agent.shell("input keyevent 66");
- sleep.millisecond(毫秒 = 300);
- print.log("✓ 标题输入完成");
- 标题输入成功 = true;
- }
- }
- sleep.second(秒 = 2);
- // ========================================
- // 步骤5:输入文章正文(WebView编辑器)
- // ========================================
- print.log("\n========== 步骤5:输入文章正文 ==========");
- var 正文输入成功 = false;
- var 尝试次数5 = 0;
- var 最大尝试次数5 = 3;
- while (!正文输入成功 && 尝试次数5 < 最大尝试次数5) {
- 尝试次数5++;
- var 编辑页面UI2 = 获取UI();
- var xml长度5 = 字符串长度(编辑页面UI2);
-
- print.log("第 " + 尝试次数5 + " 次尝试获取编辑页面UI,长度:" + xml长度5);
-
- if (xml长度5 < 100) {
- print.log("UI数据过短,重试");
- sleep.second(秒 = 1);
- continue;
- }
-
- var webView节点2 = 查找WebView节点(编辑页面UI2);
-
- if (webView节点2.length > 0) {
- var webView2 = webView节点2[0];
- var 点击X2 = (webView2.x1 + webView2.x2) / 2 / 屏幕宽;
- var 点击Y2 = (webView2.y1 + webView2.y2) / 2 / 屏幕高;
- print.log("✓ 准备在WebView正文区域输入,百分比坐标:(" + 点击X2.toFixed(4) + ", " + 点击Y2.toFixed(4) + ")");
-
- 输入文本(文章正文, 点击X2, 点击Y2);
- sleep.millisecond(毫秒 = 500);
- print.log("✓ 正文输入完成");
- 正文输入成功 = true;
- } else {
- print.log("⚠ 未找到WebView节点,尝试点击页面中间区域");
- 输入文本(文章正文, 0.3, 0.4);
- sleep.millisecond(毫秒 = 500);
- print.log("✓ 正文输入完成");
- 正文输入成功 = true;
- }
- }
- sleep.second(秒 = 2);
- // ========================================
- // 步骤6:点击发布按钮
- // ========================================
- print.log("\n========== 步骤6:点击发布按钮 ==========");
- var 找到发布按钮 = false;
- var 尝试次数6 = 0;
- var 最大尝试次数6 = 3;
- while (!找到发布按钮 && 尝试次数6 < 最大尝试次数6) {
- 尝试次数6++;
- var 编辑页面UI3 = 获取UI();
- var xml长度6 = 字符串长度(编辑页面UI3);
-
- print.log("第 " + 尝试次数6 + " 次尝试获取编辑页面UI,长度:" + xml长度6);
-
- if (xml长度6 < 100) {
- print.log("UI数据过短,重试");
- sleep.second(秒 = 1);
- continue;
- }
-
- var 发布节点 = 查找包含文字的节点(编辑页面UI3, ["发布", "发布文章", "保存", "完成"]);
-
- if (发布节点.length > 0) {
- var 发布按钮 = 发布节点[0];
- var 发布X = (发布按钮.x1 + 发布按钮.x2) / 2 / 屏幕宽;
- var 发布Y = (发布按钮.y1 + 发布按钮.y2) / 2 / 屏幕高;
- agent.clickPercent(发布X, 发布Y);
- print.log("✓ 已点击「" + 发布按钮.text + "」,百分比坐标:(" + 发布X.toFixed(4) + ", " + 发布Y.toFixed(4) + ")");
- 找到发布按钮 = true;
- } else {
- var 发布资源ID节点 = 查找包含资源ID的节点(编辑页面UI3, ["publish", "save", "done", "submit"]);
-
- if (发布资源ID节点.length > 0) {
- var 发布按钮 = 发布资源ID节点[0];
- var 发布X = (发布按钮.x1 + 发布按钮.x2) / 2 / 屏幕宽;
- var 发布Y = (发布按钮.y1 + 发布按钮.y2) / 2 / 屏幕高;
- agent.clickPercent(发布X, 发布Y);
- print.log("✓ 已点击发布按钮(通过资源ID),百分比坐标:(" + 发布X.toFixed(4) + ", " + 发布Y.toFixed(4) + ")");
- 找到发布按钮 = true;
- } else {
- print.log("⚠ 未找到发布按钮,尝试点击右上角");
- agent.clickPercent(0.9, 0.07);
- print.log("✓ 使用默认坐标点击右上角");
- 找到发布按钮 = true;
- }
- }
- }
- if (!找到发布按钮) {
- print.log("✗ 多次尝试未找到发布按钮");
- }
- sleep.second(秒 = 3);
- // ========================================
- // 步骤7:关闭APP
- // ========================================
- print.log("\n========== 步骤7:关闭APP ==========");
- try {
- agent.shell("am force-stop " + APP包名);
- print.log("✓ 已关闭简书");
- } catch (e) {
- print.log("⚠ 关闭APP失败:" + e.message);
- }
- sleep.second(秒 = 10);
- if (当前循环 < 循环次数) {
- print.log("\n========== 等待下一次循环 ==========");
- sleep.second(秒 = 10);
- }
- }
- // ========================================
- // 结果汇总
- // ========================================
- print.timeEnd();
- print.log("\n======================================");
- print.log("===== 简书写文章流程执行完成 =====");
- print.log("文章标题:" + 文章标题);
- print.log("文章正文长度:" + 文章正文.length + " 字");
- print.log("======================================");
复制代码
| |  | |  |
|