无需Java/Kotlin,如何用Python/ADB获取android.view.ViewGroup子元素及文本?
可以,以下几种纯Python+ADB的方案就能实现,无需Java/Kotlin
方案1:通过ADB导出UI层级解析ViewGroup子元素
直接用ADB的uiautomator dump导出当前屏幕的UI结构,再用Python解析XML获取ViewGroup及其子元素:
- 先执行ADB命令导出UI文件到本地:
adb shell uiautomator dump /sdcard/ui_dump.xml adb pull /sdcard/ui_dump.xml ./ - 用Python内置的XML解析库处理,遍历ViewGroup并提取子元素:
import xml.etree.ElementTree as ET tree = ET.parse('ui_dump.xml') root = tree.getroot() # 遍历所有ViewGroup节点 for view_group in root.findall(".//*[@class='android.view.ViewGroup']"): # 获取该ViewGroup下的所有子元素 children = view_group.findall("./*") for child in children: # 提取子元素的类名、位置、文本等属性 print(f"子元素类名: {child.get('class')}, 位置: {child.get('bounds')}, 文本: {child.get('text') or '无'}") - 提示:屏幕显示的文本大概率是ViewGroup的子元素(比如TextView)承载的,重点遍历子元素的
text字段即可。
方案2:用Python的uiautomator2库简化操作
这是Python封装的UIAutomator工具,无需Java环境,直接调用就能定位控件:
- 先安装库:
pip install uiautomator2 - 连接设备后定位ViewGroup并获取子元素:
import uiautomator2 as u2 d = u2.connect() # 自动连接模拟器/真机 # 定位所有ViewGroup控件 view_groups = d.xpath("//android.view.ViewGroup") for vg in view_groups.all(): # 获取当前ViewGroup的所有子元素 children = vg.children() for child in children: # 尝试提取文本,获取控件属性 text = child.text if text: print(f"子元素文本: {text}, 位置: {child.bounds}") print(f"子元素类名: {child.info['className']}")
- 针对elementId不固定的问题,这个库支持用控件位置(bounds)、子元素特征、层级关系来定位,完全不需要依赖不稳定的elementId。
方案3:截图+OCR提取隐藏文本
如果ViewGroup的文本完全不暴露在UI层级(比如是Canvas绘制的),就用ADB截图后通过OCR识别:
- 安装依赖库:
pip install pytesseract pillow - 实现截图、裁剪、识别的流程:
import os from PIL import Image import pytesseract # 截图并拉取到本地 os.system("adb shell screencap /sdcard/screen.png") os.system("adb pull /sdcard/screen.png ./") # 先通过UI层级获取目标ViewGroup的bounds,比如解析得到坐标[100,200][300,400] left, top, right, bottom = 100, 200, 300, 400 # 裁剪出ViewGroup对应的区域 img = Image.open('screen.png') cropped_img = img.crop((left, top, right, bottom)) # OCR识别文本(根据实际语言调整lang参数,比如'chi_sim'是简体中文) text = pytesseract.image_to_string(cropped_img, lang='chi_sim') print(f"识别到的文本: {text.strip()}")
- 注意:需要提前安装Tesseract引擎,不同分辨率的模拟器要对应调整裁剪坐标。
关于elementId不固定的替代方案
完全放弃elementId,改用以下稳定的定位方式:
- 用ViewGroup的
bounds坐标(模拟器分辨率固定的话,坐标不会变) - 结合子元素的特征(比如子元素的类名数量、文本内容)
- 依托父控件的层级关系定位(比如某ViewGroup是某个固定控件的子元素)
内容的提问来源于stack exchange,提问作者regregoff
相关产品推荐
相关产品推荐

