使用AI来实现拼夕夕自动化运营脚本
AI编程是当前最热门的话题之一指的是大模型来辅助人类进行编程甚至由AI自动生成代码。这个过程通常被称为AI代码生成或AI辅助编程。常见的AI编程工具GitHub Copilot基于OpenAI的Codex模型能根据你的注释或代码上下文自动建议和生成代码。Amazon CodeWhisperer亚马逊推出的类似工具。Tabnine一款专注于代码补全的AI助手。通义灵码阿里、CodeGeeX智谱等国内优秀的同类产品。大型语言模型直接使用ChatGPT、Claude、DeepSeek Code等聊天机器人通过自然语言描述来生成代码片段。自动化脚本Automation Scripts是指编写一些小程序通常用Python, JavaScript等语言来自动执行重复、繁琐的计算机任务从而解放人力提高效率和准确性。AI编程极大地降低了编写这类脚本的门槛并提升了开发效率。一、准备工作准备一台手机并安装冰狐打开调试模式。配置好大模型参数推荐使用deepseek。二、梳理需求我们总体需求是实现拼夕夕自动化运营。但是仅仅这样的比较笼统的、大概的需求还是不够的我们必须尽量细化否则AI可能无法正确返回结果。如何来细化需求呢核心原则是我们自己手工按需求实际操作下把每一步的操作记录下来一般就是我们最终的细化需求了。下面我们就具体来看下如何细化需求打开拼夕夕打开拼夕夕后需要判断是否成功进入了拼夕夕可以我们可以选择使用“首页”和“个人中心”来做判断。点击进入搜索页面点击顶部的搜索框进入搜索页面通过分析ui树发现无法直接点击搜索框但是可以通过点击“照相机”左边偏移50像素位置进入搜索框。搜索在搜索页面中直接在类名为android.widget.EditText的控件中输入商品名比如“手机”然后点击搜索按钮进入搜索结果页面。循环遍历处理在搜索结果页面中循环处理每一个结果注意这里循环处理的是id为com.xunmeng.pinduoduo:id/tv_title的控件。找到商品店铺上一步找到的title控件点击它进入商品页面如果找到“客服”文本则说明进入了商品页面然后滑动屏幕直到找到“进店”文本为止。通过分析ui树得出进店控件的family取值为[0, 2, 1, 1]即为店铺名。三、生成脚本总结第二步的细化后的ai需求为“打开拼xx若找到“首页”或者“个人中心”则表示成功进入拼夕夕。点击文本为“拍照搜索”且类名为android.widget.ImageView控件的左边50个像素位置进入含有类名为android.widget.EditText控件的页面。在该控件中输入文本“手机”然后点击文本为“搜索”的按钮进入含有id为com.xunmeng.pinduoduo:id/tv_title的搜索结果页面。在搜索界面页面中循环遍历处理id为com.xunmeng.pinduoduo:id/tv_title的所有控件用文本“拍照搜索”来判断是否为搜索结果面。具体处理为点击控件进入含有文本为“客服”控件的页面查找文本为“进店”的控件如果找不到则向上滚动页面后继续查找最多滚动5次如果找到则获取控件的famliy为[0, 2, 1, 1]的控件的文本。”。直接提交给AIAI思考几秒后就会给出对应的代码。// 循环遍历处理 function _loopDeal(fnGetContainer, fnGetTitle, fnTask, options) { var dealedArr [], scrollCount 0; var cbItemFilter options options.cbItemFilter ? options.cbItemFilter : null; var backTag options options.backTag ? options.backTag : ; var endTag options options.endTag ? options.endTag : ; var maxConsecutiveScrollCount options options.maxConsecutiveScrollCount ? options.maxConsecutiveScrollCount : 3; console.log(backTag:, backTag, endTag:, endTag, maxConsecutiveScrollCount:, maxConsecutiveScrollCount); while (true) { var container fnGetContainer(); if (container) { var find false; // 遍历找到的所有目标 for (var item of container) { // 过滤掉无效的item if (!cbItemFilter || cbItemFilter(item)) { // 获取title排除空 var title fnGetTitle(item); if (strIsNotEmpty(title.trim())) { if (!dealedArr.includes(title)) { console.log(处理 title); find true; dealedArr.push(title); // 执行任务 var r fnTask(item); console.log(执行任务结果: r); // 返回到容器界面 if (backTag) { var b back2Page(backTag, { backFirst: false, maxStep: 8 }); console.log(back b: b); } break; } } } } if (!find) { // 检查是否到达容器底部 if (endTag) { if (findView(endTag, { maxStep: 2 }).length 0) { console.log(找到结束Tag: endTag , 退出); break; } } // 检查是否达到最大连续滑动次数 if (scrollCount maxConsecutiveScrollCount) { console.log(超过最大连续滑动次数认为已经到达底部退出); break; } console.log(没找到有效的目标item滑动); scroll(up, { afterWait: 1000 }); scrollCount; } else { scrollCount 0; } } else { console.log(没找到容器退出); break; } } } function main() { // 启动拼夕夕APP if (1 ! launchApp(com.xunmeng.pinduoduo)) { console.error(启动拼夕夕失败); return; } console.log(启动拼夕夕成功); // 等待进入首页或个人中心 var ret findView(txt:首页|txt:个人中心, {maxStep: 10}); if (ret.length 0) { console.error(未找到首页或个人中心可能未成功进入拼夕夕); return; } console.log(成功进入拼夕夕); // 点击拍照搜索控件左边50像素位置 ret findView(txt:拍照搜索cn:android.widget.ImageView); if (ret.length 0) { console.error(未找到拍照搜索控件); return; } var view ret.views[0]; // 点击控件左边50像素位置 gestureClick(view.left - 50, view.top view.height / 2, {afterWait: 1000}); // 等待进入含有EditText的页面 ret findView(cn:android.widget.EditText, {maxStep: 10}); if (ret.length 0) { console.error(未进入搜索页面); return; } console.log(进入搜索页面); // 在EditText中输入手机 paste(cn:android.widget.EditText, 手机, {afterWait: 1000}); // 点击搜索按钮 click(txt:搜索, {click: true, afterWait: 2000}); // 等待进入搜索结果页面 ret findView(id:com.xunmeng.pinduoduo:id/tv_title, {maxStep: 10}); if (ret.length 0) { console.error(未进入搜索结果页面); return; } console.log(进入搜索结果页面); // 循环处理搜索结果 _loopDeal(getContainer, getTitle, task, {backTag:txt:拍照搜索}); } // 弹窗处理 function e1() { var ret findView(txt:取消|txt:关闭|id:com.xunmeng.pinduoduo:id/close, {maxStep: 1}); if (ret.length 0) { click(ret.views[0], {click: true}); sleep(500); } } function getContainer() { return findView(id:com.xunmeng.pinduoduo:id/tv_title, {flag: find_all, failed: e1}).views; } function getTitle(item) { return item.text; } function task(item) { // 点击控件进入详情页 if (!switchPage(item, txt:客服, {failed: e1}).length 0) { console.log(进入详情页失败); return false; } console.log(进入详情页); // 查找进店控件最多滚动5次 var scrollCount 0; var ret; while (scrollCount 5) { ret findView(txt:进店, {maxStep: 2}); if (ret.length 0) { console.log(找到进店控件); // 获取family为[0, 2, 1, 1]的控件文本 var targetView ret.views[0].family([0, 2, 1, 1]); if (targetView) { console.log(目标控件文本:, targetView.text); } break; } console.log(未找到进店控件向上滚动); scroll(up, {afterWait: 1000}); scrollCount; } if (scrollCount 5) { console.log(滚动5次后仍未找到进店控件); } return true; }四、调试运行直接在左上脚点击“调试运行”即可执行脚本在执行的过程中左下角会有对应的log可以通过log大概看到脚本执行的情况。详细如下图所示。