最近在写安卓页面元素的xpath,不清楚自己写的对不对,就写个小脚本验证一下。
脚本会查找当前目录下所有的 .uix
文件,读取此文件,验证是否能找到相应的 xpath,如果能找到 xpath,则会打开和 .uix
同名的 .png
图片,在此图片上绘制 xpath 所定位的元素的位置。
ps. 命令行 dump UI界面和图片
adb root
adb shell uiautomator dump /sdcard/app.uix
adb shell screencap -p /sdcard/app.png
adb pull /sdcard/app.uix
adb pull /sdcard/app.png
# coding:utf-8
import cv2
from pathlib import Path
import lxml.etree as etree
import re
def locate_element(pic_name,x0,y0,x1,y1):
img = cv2.imread(pic_name)
# crop =img[y0:y1,x0:x1] # 截图
# 画一个方框
draw = cv2.rectangle(img,(x0,y0),(x1,y1),(255,0,0),2)
x,y = img.shape[0:2]
# 重新设置图片大小为原来的一半
draw_2 = cv2.resize(draw,(int(y/2),int(x/2)))
# 移动窗口位置
cv2.namedWindow(pic_name)
cv2.moveWindow(pic_name, 40, 30)
# 显示图片
cv2.imshow(pic_name,draw_2)
cv2.waitKey()
def get_xpath(file_name,xpath_str):
"""
读取文件,并测试 xpath 是否存在
:param file_name: uiautomator dump file: .uix
:param xpath_str: xpath
:return:
"""
html = open(file_name,'r',encoding='utf-8').read()
selector = etree.HTML(html.encode('utf-8')) # 不加 encode,会报错,不清楚为啥
items = selector.xpath(xpath_str)
if items:
for item in items:
# print(item.attrib)
# 获取当前 element 的边界坐标值
bounds = item.attrib['bounds']
bounds = re.split(r'[][,]',bounds)
bounds = [int(bound) for bound in bounds if bound]
# 将 element 的坐标值传递给图片,绘制出来所在位置
locate_element(file_name.replace('uix','png'),*bounds)
else:
print('None.')
cur = Path()
xpath_str = input("Your test xpath:") # xpath字符串,如://*[@content-desc='radio']
for file in cur.iterdir():
if file.suffix == '.uix':
get_xpath(str(file),xpath_str)