我的手是小米note9pro,系统是:安卓12、MIUI14。抖音版本是34.0.0。现在打算用脚本去读取抖音中的文字内容,请问该怎么实现?比如:要在抖音的消息页中找出(新关注我的)?目前试过用遍历控件也找不到?
我要在抖音的消息页内找到(新关注我的)。目前(新关注我的)在页面可见位置,可以真确识别找到。如不在可见范围就找不到。请问怎么增加向上的滑屏功能,每滑屏一次,再找(新关注我的)。技术怎么实现?

问题:抖音消息页「新关注我的」是自定义渲染文字,text () 取不到内容,只能画布绘制;
1.这类原生绘制文字除 OCR 外,有没有无障碍取字方案?
2.抖音消息列表条目红点 ImageView 固定在条目右上角,能否通过红点控件反向锁定整行条目(不用识别标题文字)?
3.消息页栏目排序固定:新关注我的→互动消息→私信,能不能按条目上下顺序 + 红点做序号定位?
请给出技术开发方向,谢谢
回答
在抖音等高频更新的应用中,直接使用控件遍历或固定 id 查找经常失败,主要原因包括:UI 动态渲染、控件属性混淆、列表懒加载以及 MIUI 12/14 的无障碍服务优化。针对你的设备与抖音 34.0.0 版本,以下是稳定读取“新关注我的”文字内容的实现方案。
核心实现步骤
- 优先使用文本/描述匹配:抖音的
id会随版本频繁变更,text()和desc()是最稳定的选择。 - 增加页面加载等待:消息页进入后需要网络请求与列表渲染,直接查找会返回空。
- 使用布局分析确认属性:在 Hamibot 控制台或设备调试中打开抖音消息页,使用“布局分析”查看目标控件的实际
text、desc、className及层级关系。
兼容脚本示例
// 文档地址 https://docs.hamibot.com/
// 清理残留线程,避免多次运行冲突
threads.shutDownAll();
// 1. 确保已停留在消息页
if (!text("消息").exists()) {
click("消息");
sleep(1500);
}
// 2. 等待目标文字出现(最多等待 5 秒)
var target = text("新关注我的").findOne(5000);
if (!target) {
target = desc("新关注我的").findOne(2000);
}
if (!target) {
target = textContains("新关注我的").findOne(2000);
}
// 3. 处理查找结果
if (target) {
log("成功找到控件,文本内容: " + target.text());
// 如需点击该条目
target.click();
} else {
log("未找到目标控件。请检查:1. 页面是否完全加载 2. 抖音版本是否变更了文案 3. 使用布局分析确认实际属性");
}
关键调试与优化建议
- 布局分析必做:抖音的“新关注我的”可能嵌套在
RecyclerView的子项中,或实际显示为“新关注我的用户”。务必在 Hamibot 的布局分析中点击该文字,查看返回的text是否包含空格、换行或前后缀。若存在前后缀,改用textContains("新关注我的")或textMatches(/.*新关注我的.*/)。 - 处理列表滚动:如果该提示不在首屏可见区域,需先滚动消息列表:
var list = className("androidx.recyclerview.widget.RecyclerView").findOne(); if (list) { list.scrollForward(); sleep(800); } - MIUI 无障碍权限:安卓 12/MIUI 14 对后台无障碍服务限制较严。确保 Hamibot 已开启“无障碍服务”、“后台弹出界面”、“自启动”权限,并在开发者选项中关闭“MIUI 优化”(如遇到控件树获取不全)。
- 稳定性增强:抖音页面元素加载存在异步延迟,建议在关键操作前加入
sleep(500)或使用waitFor()轮询检测。避免使用固定id选择器,优先依赖text、desc、className组合定位。
按上述逻辑调整后,脚本即可稳定识别并读取目标文字。如布局分析显示该文字实际由多个子控件拼接渲染,可改用 parent().findOne(text("新关注我的")) 向上追溯父容器后再操作。
在抖音消息页中实现“滑动查找”功能,核心在于准确定位可滚动容器、控制滑动节奏以及设置查找超时防卡死。以下是针对你设备与抖音版本的完整实现方案:
核心实现代码
// 文档地址 https://docs.hamibot.com/
threads.shutDownAll();
var maxScrolls = 15; // 最大滑动次数,防止死循环
var targetText = "新关注我的";
var found = false;
// 1. 确保停留在消息页
if (!text("消息").exists()) {
click("消息");
sleep(1500);
}
// 2. 定位可滚动列表容器(优先 RecyclerView,兼容旧版 AbsListView)
var scrollContainer = className("androidx.recyclerview.widget.RecyclerView").findOne(2000);
if (!scrollContainer) {
scrollContainer = className("AbsListView").findOne(2000);
}
// 3. 循环滑动并查找
for (var i = 0; i < maxScrolls; i++) {
log("第 " + (i + 1) + " 次查找");
// 使用带超时的 findOne 避免阻塞
var target = text(targetText).findOne(500);
if (!target) {
target = textContains(targetText).findOne(500);
}
if (target) {
log("成功找到目标控件");
found = true;
break;
}
// 执行上滑操作
if (scrollContainer && scrollContainer.scrollable()) {
scrollContainer.scrollForward();
} else {
// 备用方案:屏幕中央向上滑动
swipe(device.width / 2, device.height * 0.75, device.width / 2, device.height * 0.25, 600);
}
// 等待滑动动画结束与列表懒加载渲染
sleep(800);
}
if (!found) {
log("已滑动 " + maxScrolls + " 次,仍未找到目标");
}
关键技术点解析
- 容器定位优先于全局滑动:抖音消息列表是典型的
RecyclerView。直接对容器调用scrollForward()比swipe()更稳定,能触发列表的懒加载机制,避免滑出屏幕外导致控件树丢失。 - 防卡死设计:
findOne(500)设置了 500ms 超时。若使用无参数的findOne(),脚本会无限期阻塞等待控件出现,导致后续滑动无法执行。 - 滑动方向说明:
scrollForward()在垂直列表中表现为向下滑动列表(手指上滑动作),用于加载下方内容。若目标在屏幕上方,需改用scrollBackward()或调整swipe的起止坐标。 - 循环终止条件:通过
maxScrolls限制最大尝试次数。抖音消息列表到底部后继续滑动会触发回弹,脚本不会无限执行。
针对抖音与 MIUI 14 的调试建议
- 布局分析确认容器:在 Hamibot 控制台打开抖音消息页,点击“布局分析”。查看列表根节点的
className是否为androidx.recyclerview.widget.RecyclerView。若抖音版本更新导致类名变更,需同步修改代码中的选择器。 - 处理动态渲染延迟:抖音列表项采用异步加载。
sleep(800)是经验值,若网络较慢可调整为1000~1200。也可改用waitFor()轮询检测列表高度变化,但会增加代码复杂度。 - MIUI 无障碍优化干扰:安卓 12/MIUI 14 会合并或隐藏部分控件。若
text()始终返回空,请在布局分析中查看该文字是否被包裹在View或TextView中,尝试改用desc("新关注我的")或className("TextView").textContains("新关注我的")。 - 滑动失效排查:若
scrollForward()无响应,说明容器未正确获取或scrollable属性为false。此时可回退到swipe(),并确保 Hamibot 已授予“无障碍服务”与“后台弹出界面”权限。
按此逻辑部署后,脚本即可自动遍历列表并精准定位目标文字。如需在找到后执行点击或提取相邻控件信息,可在 if (target) 分支内追加 target.click() 或 target.parent().findOne(text("xxx"))。
针对抖音自定义渲染文字与列表定位需求,以下是明确的技术实现方向与代码方案。
1. 无障碍服务能否读取 Canvas 绘制文字?
结论:不能。 Android 无障碍服务(AccessibilityService)依赖 View 树节点属性(如 text、contentDescription)。若文字通过 Canvas.drawText() 或自定义 View 的 onDraw() 直接绘制,系统无障碍树中不会生成对应文本节点,这是 Android 底层架构限制。
可行路径:
- 优先检查
desc()或contentDescription。部分版本可能为无障碍预留描述,但抖音通常留空或返回通用值,稳定性极低。 - 若必须获取该文字内容,OCR 是唯一可靠方案。Hamibot 内置
images.ocr()或可接入 PaddleOCR 插件,通过截取列表区域进行文字识别。
2. 通过红点 ImageView 反向锁定整行条目
技术方向: 利用无障碍树的父子节点关系向上遍历,直到命中列表行容器。列表行通常具备 clickable=true、固定高度或特定布局类名。
实现代码:
// 文档地址 https://docs.hamibot.com/
// 1. 定位红点(需根据实际布局分析调整过滤条件)
var redDots = className("ImageView").find();
var targetDot = null;
for (var i = 0; i < redDots.length; i++) {
var b = redDots[i].bounds();
// 过滤:尺寸小、位于屏幕右侧、通常为未读红点
if (b.width() < 35 && b.height() < 35 && b.left > device.width * 0.75) {
targetDot = redDots[i];
break;
}
}
if (targetDot) {
// 2. 向上遍历查找列表行容器
var row = targetDot.parent();
while (row) {
// 命中条件:可点击 或 高度符合列表项特征(如 120~200px)
var h = row.bounds().height();
if (row.clickable() || (h > 100 && h < 250)) {
log("已锁定整行条目");
row.click(); // 或提取 row 内其他子控件
break;
}
row = row.parent();
}
} else {
log("未找到符合条件的红点控件");
}
3. 按固定顺序 + 红点做序号定位
技术方向: 获取页面所有红点控件,按垂直坐标 bounds().top 升序排序。抖音消息页栏目顺序固定,排序后索引 0 对应“新关注我的”,索引 1 对应“互动消息”,依此类推。结合红点反向锁定逻辑即可精准操作。
实现代码:
// 文档地址 https://docs.hamibot.com/
var allDots = className("ImageView").find();
var validDots = [];
// 过滤有效红点
for (var i = 0; i < allDots.length; i++) {
var b = allDots[i].bounds();
if (b.width() < 35 && b.height() < 35 && b.left > device.width * 0.75) {
validDots.push(allDots[i]);
}
}
// 按垂直位置从上到下排序
validDots.sort(function(a, b) {
return a.bounds().top - b.bounds().top;
});
// 序号定位:0=新关注我的,1=互动消息,2=私信
var targetIndex = 0; // 修改此处切换目标
if (validDots.length > targetIndex) {
var dot = validDots[targetIndex];
var row = dot.parent();
while (row && !row.clickable()) {
row = row.parent();
if (!row) break;
}
if (row) {
log("通过序号 " + targetIndex + " 定位成功,执行点击");
row.click();
}
} else {
log("当前页面红点数量不足,无法定位到序号 " + targetIndex);
}
核心稳定性建议
- 避免硬编码
id:抖音 34.0.0 的控件id会随热更新频繁变更,优先使用className+bounds()范围过滤。 - MIUI 14 无障碍限制:安卓 12 对后台无障碍服务有严格管控。确保 Hamibot 已开启“无障碍服务”、“后台弹出界面”、“自启动”,并在开发者选项中关闭“MIUI 优化”(若出现控件树缺失或滑动失效)。
- 滑动与查找节奏:列表懒加载会导致控件树动态变化。每次滑动后必须加入
sleep(600~1000)等待渲染完成,再执行查找逻辑。 - 防误触过滤:红点尺寸与位置是核心过滤条件。若抖音版本更新导致红点样式变化,需在 Hamibot 控制台使用“布局分析”重新测量
width、height与left阈值。
按上述方向开发,可完全绕过 Canvas 文字限制,通过红点坐标与树遍历实现高可靠定位。如需进一步适配特定抖音版本或处理复杂嵌套结构,可提供布局分析截图中的节点属性,我将为你调整选择器逻辑。