最近闲着没事,用 AutoJS 撸了个微博自动化小工具,主要是解决每天签到、发超话这些重复操作。代码整体不复杂,但一些细节处理起来挺有意思,趁热记录一下,也分享给有类似需求的朋友。
先说下功能,这个脚本目前支持三件事:
- 自动完成每日签到(那个+0.2积分,虽然少但强迫症必须点)
- 按指定文本发布一条普通微博
- 自动进入某个超话并发布帖子(文案可以自定义)
使用场景嘛,多半是养号、保持活跃度,或者单纯懒得点那几下屏幕。脚本跑在 AutoJS 上,需要开启无障碍服务,代码全是在真机和模拟器上实测过的,Android 7 到 12 都试过,MiUI 的一些坑后面会提。
签到的实现
微博签到入口藏得比较深,路径是:首页底栏「我」→ 头像下方的「签到」按钮。这个按钮控件 id 在不同版本经常变,所以我没有用 id 定位,而是直接按文本查找。
// 签到函数
function dailyCheckIn() {// 先确保在「我」的tab页let wo = text("我").findOne(3000);if (wo && wo.parent()) {clickControl(wo.parent()); // 点击父视图切换到我的页面sleep(1000);}// 在「我」的页面内找“签到”按钮let signBtn = text("签到").findOne(3000);if (signBtn) {clickControl(signBtn);sleep(1500);toast("签到完成");} else {// 可能已经签过了,或者UI改了,可以用desc再试let signByDesc = desc("签到").findOne(1000);if (signByDesc) {clickControl(signByDesc);sleep(1500);} else {toast("未找到签到入口");}}
}// 封装一个点击控件的函数,处理点击不稳定问题
function clickControl(view) {if (view && view.clickable()) {view.click();} else if (view && view.parent() && view.parent().clickable()) {view.parent().click();} else {// 兜底用坐标点击click(view.bounds().centerX(), view.bounds().centerY());}
}
这里的技巧在于 clickControl,因为有些控件本身不可点击,但它的父布局可以,需要递归向上找。另外如果通过无障碍点击失败(比如被系统屏蔽),我会用 bounds() 取中点坐标来点,兼容性会好很多。
发布普通微博
发一条文字微博的流程:点击底部「+」→ 进入发微博界面 → 输入文字 → 点击发送。这里要注意新版微博的「+」按钮在底部 tab 中间,没有文字,需要用 desc 定位。
function postWeibo(textContent) {// 点击底部的 + 按钮(contentDescription="发布"或者"发微博")let postBtn = descMatches(/发布|发微博/).findOne(5000);if (!postBtn) {// 有些版本desc就是 + 或者 写微博postBtn = desc("写微博").findOne(2000);}if (!postBtn) {toast("找不到发微博入口");return false;}clickControl(postBtn);sleep(2000);// 在新页面中定位输入框let inputField = className("EditText").findOne(3000);if (inputField) {inputField.click();sleep(500);// 输入文本inputField.setText(textContent);sleep(1000);// 找发送按钮,一般是右上角的“发送”let sendBtn = text("发送").findOne(3000);if (sendBtn) {clickControl(sendBtn);sleep(2000);toast("微博发布成功");return true;}}toast("发布流程失败");return false;
}
这里 descMatches 用的是正则,因为不同版本微博的 contentDescription 可能是“发微博”“发布”“写微博”,一下就能匹配到。输入框直接用 className("EditText") 定位,因为发微博页面就那么一个输入框,几乎不会找错。
自动发超话
这个环节最麻烦。发布超话帖子的路径是:搜索超话 → 进入超话社区 → 点击「发帖」 → 输入内容 → 选择同步到微博 → 发送。我们需要自动搜索指定超话名字,点进去,然后发帖。
function postToSuperTopic(topicName, content) {// 进入搜索页面let searchEntry = desc("搜索").findOne(3000);if (!searchEntry) {toast("找不到搜索入口");return false;}clickControl(searchEntry);sleep(1000);// 定位搜索框并输入超话名称let searchInput = className("EditText").findOne(2000);if (searchInput) {searchInput.setText(topicName);sleep(800);// 有些版本需要点击搜索按钮let searchBtn = text("搜索").findOne(2000);if (searchBtn) {searchBtn.click();} else {// 用回车事件back(); // 有的输入法需要先收起来sleep(300);shell("input keyevent KEYCODE_ENTER", true);}sleep(2000);}// 在搜索结果中找到目标超话并点击// 一般第一个就是,但为了保险,用文本精确匹配let topicItem = textContains(topicName).findOne(3000);if (topicItem) {clickControl(topicItem);sleep(1500);} else {toast("未找到该超话");return false;}// 进入超话后找发帖按钮let postEntry = text("发帖").findOne(3000) || desc("发帖").findOne(3000);if (!postEntry) {toast("找不到发帖按钮");return false;}clickControl(postEntry);sleep(1500);// 在发帖页面输入内容,与普通发微博类似let inputField = className("EditText").findOne(3000);if (inputField) {inputField.setText(content);sleep(1000);// 勾选“同步到微博”(可选的)let syncOption = text("同步到微博").findOne(1000);if (syncOption && !syncOption.checked()) {syncOption.click();sleep(500);}// 点击发送let sendBtn = text("发送").findOne(3000);if (sendBtn) {clickControl(sendBtn);sleep(2000);toast("超话发布完成");return true;}}return false;
}
超话搜索这部分有一个坑:有的输入法弹出时,EditText 的 setText 会失效,或者搜索结果列表要等一会儿才加载。我最后加上了 shell("input keyevent KEYCODE_ENTER") 来模拟回车搜索,稳定性提升不少。另外“同步到微博”这个开关有时默认是开的,我加了个判断避免重复点击。
整体调度
把上面几个函数串起来,加一个主流程,每次执行签到、发一条普通微博、再发一条超话(可以隔几分钟再发,防止被限制)。
function main() {auto.waitFor(); // 等待无障碍服务launchApp("微博");sleep(5000); // 等微博完全启动// 签到dailyCheckIn();sleep(2000);// 发一条普通微博postWeibo("今天的自动化任务完成啦 #日常打卡");sleep(3000);// 发超话帖子postToSuperTopic("每日打卡", "又是元气满满的一天!");sleep(2000);toast("所有任务完成");exit();
}main();
几个细节处理
还有几个踩过的坑值得说一下:
- 权限问题:部分 MIUI 系统,即使开启了无障碍,控件点击也会被“后台弹出界面”权限拦截,需要在应用权限里把「后台弹出界面」给 AutoJS 打开。
- 运行环境:我的 AutoJS 版本是 4.1.1,如果是 Pro 版本可能部分 API 有变化,但基本的找控件逻辑通用。
- 发包频率:脚本连续发送两条微博,最好在中间插入一个
sleep(3000),不然有可能被系统判定为频繁操作,发第二条时会失败。
这个小东西整体用了两天晚上就搞定了,大部分时间其实花在逆向找控件和兼容不同机型上。代码量不多,但实用性还挺强,每天打开 AutoJS 运行一次就可以去做别的事了。如果有类似需求的朋友可以参考改一改,适配其他 App 的套路也差不多就是这个思路。
