adbui


Nameadbui JSON
Version 4.5.22 PyPI version JSON
download
home_pagehttps://github.com/hao1032/adbui
Summaryadbui 所有的功能都是通过 adb 命令,adbui 的特色是可以通过 xpath,ocr 获取 ui 元素。
upload_time2024-05-31 08:52:49
maintainerNone
docs_urlNone
authorTango Nian
requires_pythonNone
licenseMIT
keywords testing android uiautomator ocr minicap
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 常见问题
- adbui 交流微信群,加 hao1032,备注 adbui,会拉入微信群
- 使用 ocr 提示出错,请在该页面最后查看使用 ocr 示例


# adbui
adbui 所有的功能都是通过 adb 命令,adbui 的特色是可以通过 xpath,ocr 获取 ui 元素。

## 安装
    pip install adbui

## 要求
- 在命令中可以使用 adb 命令,即adb已经配置到环境变量
- adb 的版本最好是 >= 1.0.39,用老版本的 adb 可能会有一些奇怪的问题
- 依赖的库:lxml 解析 xml,requests 发 ocr 请求,pillow 图片处理

## 说明
- adbui 当前还在完善,bug 和建议请直接在 github 反馈
- 主要在 win7,python3 环境使用,其他环境可能有问题


## import and init
    from adbui import Device

    d = Device('123abc')  # 手机的sn号,如果只有一个手机可以不写


## adbui 可以分为 3 个部分
**util 负责执行完整的命令**

  - **cmd** 用来执行系统命令
  
        d.util.cmd('adb -s 123abc reboot')
        out = d.util.cmd('ping 127.0.0.1')
    
  - **adb** 用来执行 adb 命令
  
        d.util.adb('install xxx.apk')
        d.util.adb('uninstall com.tencent.mtt')
    
  - **shell** 用来执行 shell 命令
  
        d.util.shell('pm clear com.tencent.mtt')
        d.util.shell('am force-stop com.tencent.mtt')

**adb_ext 对常用 adb 命令的封装,下面列出部分操作(可在 adbui/adb_ext.py 文件自行增加需要的操作)**

  - **screenshot**
   
        d.adb_ext.screenshot() # 截图保存到系统临时目录,也可指定目录
        
  - **click**
  
        d.adb_ext.click(10, 32)  # 执行一个点击事件 
        
  - **input**
  
        d.adb_ext.input('adbui')  # 输入文本 
        
  - **back**
  
        d.adb_ext.back()  # 发出 back 指令 


**get_ui 可以通过多种方式获取 UI**
  - **by attr** 通过在 uiautomator 里面看到的属性来获取
  
        ui = d.get_ui_by_attr(text='设置', desc='设置')  # 支持多个属性同时查找

        ui = d.get_ui_by_attr(text='设', is_contains=True)  # 支持模糊查找

        ui = d.get_ui_by_attr(text='设置', is_update=False)  # 如果需要在一个界面上获取多个 UI, 再次查找时可以设置不更新xml文件和截图,节省时间

        ui = d.get_ui_by_attr(class_='android.widget.TextView')  # class 在 python 中是关键字,因此使用 class_ 代替

        ui = d.get_ui_by_attr(desc='fffffff')  # 如果没有找到,返回 None;如果找到多个返回第一个

        ui = d.get_uis_by_attr(desc='fffffff')  # 如果是 get uis 没有找到,返回空的 list
    
  - **by xpath** 使用 xpath 来获取
        ![xpath](docs/image/xpath01.png)
  
        mic_btn = d.get_ui_by_xpath('.//FrameLayout/LinearLayout/RelativeLayout/ImageView[2]')  # 获取麦克风按钮
        mic_btn.click()  # 点击麦克风按钮
        
        # adbui 使用 lxml 解析 xml 文件,因此 by xpath 理论上支持任何标准的 xpth 路径。
        # 这里有一篇 xpath 使用的文章:https://cuiqingcai.com/2621.html
        
        # 另外获取的 ui 对象实际是一个自定义的 UI 实类,ui 有一个 element 的属性,element 就是 lxml 里面的 Element 对象,
        # 因此可以对 ui.element 执行 lxml 的相关操作。
        # lxml element 对象的文档:http://lxml.de/api/lxml.etree._Element-class.html
        
        scan_element = ui.element.getprevious()  # 获取麦克风的上一个 element,即扫一扫按钮
        scan_btn = d.get_ui_by_element(scan_element)  # 使用 element 实例化 UI
        scan_btn.click()  # 点击扫一扫按钮

  - **by ocr** 使用腾讯的OCR技术来获取
        ![xpath](docs/image/ocr01.png)
        
        d.init_ocr('10126986', 'AKIDT1Ws34B98MgtvmqRIC4oQr7CBzhEPvCL', 'AAyb3KQL5d1DE4jIMF2f6PYWJvLaeXEk')
        # 使用 ocr 功能前,必须要使用自己的开发密钥初始化,上面的密钥是我申请的公共测试密钥,要稳定使用请自行申请
        # 腾讯的 ocr 功能是免费使用的,需要自己到 http://open.youtu.qq.com/#/develop/new-join 申请自己的开发密钥
        
        btn = d.get_ui_by_ocr(text='爱拍')  # 找到爱拍文字的位置
        btn.click()  # 点击爱拍

## Change Log
20210425 version 4.5.0
- screenshot 和 dump xml 优先使用 adbui,预期速度有很大的提升
- 删除 Pillow 依赖

20210425 version 4.0.0
- screenshot 参数有变化,升级请谨慎
- 尝试尽量使用 minicap 截图
- 尝试不使用 pillow 功能

20210418 version 3.5.2
- 增加 minicap 截图

20210325 version 2.6
- dump xml 优先使用 --compressed 模式

20210325 version 2.4
- 修复python3.8以上版本找控件报错 RuntimeError: dictionary keys changed during iteration

20200402 version 1.0
- 修改screenshot 参数情况
- 去掉 cmd out save 函数
- init ocr支持keys传入多个key

20200328 version 0.40.1
- 修改 push pull 方法等参数
- 使用 timeout 库控制超时
- get ui by orc 去掉 min hit 参数,增加 is contains 参数

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/hao1032/adbui",
    "name": "adbui",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "testing android uiautomator ocr minicap",
    "author": "Tango Nian",
    "author_email": "hao1032@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/db/f0/15f00e1e1d80a3299ac77412ba2c223b6ad6eb86836d936efa0b6cc1f673/adbui-4.5.22.tar.gz",
    "platform": "any",
    "description": "# \u5e38\u89c1\u95ee\u9898\r\n- adbui \u4ea4\u6d41\u5fae\u4fe1\u7fa4\uff0c\u52a0 hao1032\uff0c\u5907\u6ce8 adbui\uff0c\u4f1a\u62c9\u5165\u5fae\u4fe1\u7fa4\r\n- \u4f7f\u7528 ocr \u63d0\u793a\u51fa\u9519\uff0c\u8bf7\u5728\u8be5\u9875\u9762\u6700\u540e\u67e5\u770b\u4f7f\u7528 ocr \u793a\u4f8b\r\n\r\n\r\n# adbui\r\nadbui \u6240\u6709\u7684\u529f\u80fd\u90fd\u662f\u901a\u8fc7 adb \u547d\u4ee4\uff0cadbui \u7684\u7279\u8272\u662f\u53ef\u4ee5\u901a\u8fc7 xpath\uff0cocr \u83b7\u53d6 ui \u5143\u7d20\u3002\r\n\r\n## \u5b89\u88c5\r\n    pip install adbui\r\n\r\n## \u8981\u6c42\r\n- \u5728\u547d\u4ee4\u4e2d\u53ef\u4ee5\u4f7f\u7528 adb \u547d\u4ee4\uff0c\u5373adb\u5df2\u7ecf\u914d\u7f6e\u5230\u73af\u5883\u53d8\u91cf\r\n- adb \u7684\u7248\u672c\u6700\u597d\u662f >= 1.0.39\uff0c\u7528\u8001\u7248\u672c\u7684 adb \u53ef\u80fd\u4f1a\u6709\u4e00\u4e9b\u5947\u602a\u7684\u95ee\u9898\r\n- \u4f9d\u8d56\u7684\u5e93\uff1alxml \u89e3\u6790 xml\uff0crequests \u53d1 ocr \u8bf7\u6c42\uff0cpillow \u56fe\u7247\u5904\u7406\r\n\r\n## \u8bf4\u660e\r\n- adbui \u5f53\u524d\u8fd8\u5728\u5b8c\u5584\uff0cbug \u548c\u5efa\u8bae\u8bf7\u76f4\u63a5\u5728 github \u53cd\u9988\r\n- \u4e3b\u8981\u5728 win7\uff0cpython3 \u73af\u5883\u4f7f\u7528\uff0c\u5176\u4ed6\u73af\u5883\u53ef\u80fd\u6709\u95ee\u9898\r\n\r\n\r\n## import and init\r\n    from adbui import Device\r\n\r\n    d = Device('123abc')  # \u624b\u673a\u7684sn\u53f7\uff0c\u5982\u679c\u53ea\u6709\u4e00\u4e2a\u624b\u673a\u53ef\u4ee5\u4e0d\u5199\r\n\r\n\r\n## adbui \u53ef\u4ee5\u5206\u4e3a 3 \u4e2a\u90e8\u5206\r\n**util \u8d1f\u8d23\u6267\u884c\u5b8c\u6574\u7684\u547d\u4ee4**\r\n\r\n  - **cmd** \u7528\u6765\u6267\u884c\u7cfb\u7edf\u547d\u4ee4\r\n  \r\n        d.util.cmd('adb -s 123abc reboot')\r\n        out = d.util.cmd('ping 127.0.0.1')\r\n    \r\n  - **adb** \u7528\u6765\u6267\u884c adb \u547d\u4ee4\r\n  \r\n        d.util.adb('install xxx.apk')\r\n        d.util.adb('uninstall com.tencent.mtt')\r\n    \r\n  - **shell** \u7528\u6765\u6267\u884c shell \u547d\u4ee4\r\n  \r\n        d.util.shell('pm clear com.tencent.mtt')\r\n        d.util.shell('am force-stop com.tencent.mtt')\r\n\r\n**adb_ext \u5bf9\u5e38\u7528 adb \u547d\u4ee4\u7684\u5c01\u88c5\uff0c\u4e0b\u9762\u5217\u51fa\u90e8\u5206\u64cd\u4f5c\uff08\u53ef\u5728 adbui/adb_ext.py \u6587\u4ef6\u81ea\u884c\u589e\u52a0\u9700\u8981\u7684\u64cd\u4f5c\uff09**\r\n\r\n  - **screenshot**\r\n   \r\n        d.adb_ext.screenshot() # \u622a\u56fe\u4fdd\u5b58\u5230\u7cfb\u7edf\u4e34\u65f6\u76ee\u5f55\uff0c\u4e5f\u53ef\u6307\u5b9a\u76ee\u5f55\r\n        \r\n  - **click**\r\n  \r\n        d.adb_ext.click(10, 32)  # \u6267\u884c\u4e00\u4e2a\u70b9\u51fb\u4e8b\u4ef6 \r\n        \r\n  - **input**\r\n  \r\n        d.adb_ext.input('adbui')  # \u8f93\u5165\u6587\u672c \r\n        \r\n  - **back**\r\n  \r\n        d.adb_ext.back()  # \u53d1\u51fa back \u6307\u4ee4 \r\n\r\n\r\n**get_ui \u53ef\u4ee5\u901a\u8fc7\u591a\u79cd\u65b9\u5f0f\u83b7\u53d6 UI**\r\n  - **by attr** \u901a\u8fc7\u5728 uiautomator \u91cc\u9762\u770b\u5230\u7684\u5c5e\u6027\u6765\u83b7\u53d6\r\n  \r\n        ui = d.get_ui_by_attr(text='\u8bbe\u7f6e', desc='\u8bbe\u7f6e')  # \u652f\u6301\u591a\u4e2a\u5c5e\u6027\u540c\u65f6\u67e5\u627e\r\n\r\n        ui = d.get_ui_by_attr(text='\u8bbe', is_contains=True)  # \u652f\u6301\u6a21\u7cca\u67e5\u627e\r\n\r\n        ui = d.get_ui_by_attr(text='\u8bbe\u7f6e', is_update=False)  # \u5982\u679c\u9700\u8981\u5728\u4e00\u4e2a\u754c\u9762\u4e0a\u83b7\u53d6\u591a\u4e2a UI\uff0c \u518d\u6b21\u67e5\u627e\u65f6\u53ef\u4ee5\u8bbe\u7f6e\u4e0d\u66f4\u65b0xml\u6587\u4ef6\u548c\u622a\u56fe\uff0c\u8282\u7701\u65f6\u95f4\r\n\r\n        ui = d.get_ui_by_attr(class_='android.widget.TextView')  # class \u5728 python \u4e2d\u662f\u5173\u952e\u5b57\uff0c\u56e0\u6b64\u4f7f\u7528 class_ \u4ee3\u66ff\r\n\r\n        ui = d.get_ui_by_attr(desc='fffffff')  # \u5982\u679c\u6ca1\u6709\u627e\u5230\uff0c\u8fd4\u56de None;\u5982\u679c\u627e\u5230\u591a\u4e2a\u8fd4\u56de\u7b2c\u4e00\u4e2a\r\n\r\n        ui = d.get_uis_by_attr(desc='fffffff')  # \u5982\u679c\u662f get uis \u6ca1\u6709\u627e\u5230\uff0c\u8fd4\u56de\u7a7a\u7684 list\r\n    \r\n  - **by xpath** \u4f7f\u7528 xpath \u6765\u83b7\u53d6\r\n        ![xpath](docs/image/xpath01.png)\r\n  \r\n        mic_btn = d.get_ui_by_xpath('.//FrameLayout/LinearLayout/RelativeLayout/ImageView[2]')  # \u83b7\u53d6\u9ea6\u514b\u98ce\u6309\u94ae\r\n        mic_btn.click()  # \u70b9\u51fb\u9ea6\u514b\u98ce\u6309\u94ae\r\n        \r\n        # adbui \u4f7f\u7528 lxml \u89e3\u6790 xml \u6587\u4ef6\uff0c\u56e0\u6b64 by xpath \u7406\u8bba\u4e0a\u652f\u6301\u4efb\u4f55\u6807\u51c6\u7684 xpth \u8def\u5f84\u3002\r\n        # \u8fd9\u91cc\u6709\u4e00\u7bc7 xpath \u4f7f\u7528\u7684\u6587\u7ae0\uff1ahttps://cuiqingcai.com/2621.html\r\n        \r\n        # \u53e6\u5916\u83b7\u53d6\u7684 ui \u5bf9\u8c61\u5b9e\u9645\u662f\u4e00\u4e2a\u81ea\u5b9a\u4e49\u7684 UI \u5b9e\u7c7b\uff0cui \u6709\u4e00\u4e2a element \u7684\u5c5e\u6027\uff0celement \u5c31\u662f lxml \u91cc\u9762\u7684 Element \u5bf9\u8c61\uff0c\r\n        # \u56e0\u6b64\u53ef\u4ee5\u5bf9 ui.element \u6267\u884c lxml \u7684\u76f8\u5173\u64cd\u4f5c\u3002\r\n        # lxml element \u5bf9\u8c61\u7684\u6587\u6863\uff1ahttp://lxml.de/api/lxml.etree._Element-class.html\r\n        \r\n        scan_element = ui.element.getprevious()  # \u83b7\u53d6\u9ea6\u514b\u98ce\u7684\u4e0a\u4e00\u4e2a element\uff0c\u5373\u626b\u4e00\u626b\u6309\u94ae\r\n        scan_btn = d.get_ui_by_element(scan_element)  # \u4f7f\u7528 element \u5b9e\u4f8b\u5316 UI\r\n        scan_btn.click()  # \u70b9\u51fb\u626b\u4e00\u626b\u6309\u94ae\r\n\r\n  - **by ocr** \u4f7f\u7528\u817e\u8baf\u7684OCR\u6280\u672f\u6765\u83b7\u53d6\r\n        ![xpath](docs/image/ocr01.png)\r\n        \r\n        d.init_ocr('10126986', 'AKIDT1Ws34B98MgtvmqRIC4oQr7CBzhEPvCL', 'AAyb3KQL5d1DE4jIMF2f6PYWJvLaeXEk')\r\n        # \u4f7f\u7528 ocr \u529f\u80fd\u524d\uff0c\u5fc5\u987b\u8981\u4f7f\u7528\u81ea\u5df1\u7684\u5f00\u53d1\u5bc6\u94a5\u521d\u59cb\u5316\uff0c\u4e0a\u9762\u7684\u5bc6\u94a5\u662f\u6211\u7533\u8bf7\u7684\u516c\u5171\u6d4b\u8bd5\u5bc6\u94a5\uff0c\u8981\u7a33\u5b9a\u4f7f\u7528\u8bf7\u81ea\u884c\u7533\u8bf7\r\n        # \u817e\u8baf\u7684 ocr \u529f\u80fd\u662f\u514d\u8d39\u4f7f\u7528\u7684\uff0c\u9700\u8981\u81ea\u5df1\u5230 http://open.youtu.qq.com/#/develop/new-join \u7533\u8bf7\u81ea\u5df1\u7684\u5f00\u53d1\u5bc6\u94a5\r\n        \r\n        btn = d.get_ui_by_ocr(text='\u7231\u62cd')  # \u627e\u5230\u7231\u62cd\u6587\u5b57\u7684\u4f4d\u7f6e\r\n        btn.click()  # \u70b9\u51fb\u7231\u62cd\r\n\r\n## Change Log\r\n20210425 version 4.5.0\r\n- screenshot \u548c dump xml \u4f18\u5148\u4f7f\u7528 adbui\uff0c\u9884\u671f\u901f\u5ea6\u6709\u5f88\u5927\u7684\u63d0\u5347\r\n- \u5220\u9664 Pillow \u4f9d\u8d56\r\n\r\n20210425 version 4.0.0\r\n- screenshot \u53c2\u6570\u6709\u53d8\u5316\uff0c\u5347\u7ea7\u8bf7\u8c28\u614e\r\n- \u5c1d\u8bd5\u5c3d\u91cf\u4f7f\u7528 minicap \u622a\u56fe\r\n- \u5c1d\u8bd5\u4e0d\u4f7f\u7528 pillow \u529f\u80fd\r\n\r\n20210418 version 3.5.2\r\n- \u589e\u52a0 minicap \u622a\u56fe\r\n\r\n20210325 version 2.6\r\n- dump xml \u4f18\u5148\u4f7f\u7528 --compressed \u6a21\u5f0f\r\n\r\n20210325 version 2.4\r\n- \u4fee\u590dpython3.8\u4ee5\u4e0a\u7248\u672c\u627e\u63a7\u4ef6\u62a5\u9519 RuntimeError: dictionary keys changed during iteration\r\n\r\n20200402 version 1.0\r\n- \u4fee\u6539screenshot \u53c2\u6570\u60c5\u51b5\r\n- \u53bb\u6389 cmd out save \u51fd\u6570\r\n- init ocr\u652f\u6301keys\u4f20\u5165\u591a\u4e2akey\r\n\r\n20200328 version 0.40.1\r\n- \u4fee\u6539 push pull \u65b9\u6cd5\u7b49\u53c2\u6570\r\n- \u4f7f\u7528 timeout \u5e93\u63a7\u5236\u8d85\u65f6\r\n- get ui by orc \u53bb\u6389 min hit \u53c2\u6570\uff0c\u589e\u52a0 is contains \u53c2\u6570\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "adbui \u6240\u6709\u7684\u529f\u80fd\u90fd\u662f\u901a\u8fc7 adb \u547d\u4ee4\uff0cadbui \u7684\u7279\u8272\u662f\u53ef\u4ee5\u901a\u8fc7 xpath\uff0cocr \u83b7\u53d6 ui \u5143\u7d20\u3002",
    "version": "4.5.22",
    "project_urls": {
        "Homepage": "https://github.com/hao1032/adbui"
    },
    "split_keywords": [
        "testing",
        "android",
        "uiautomator",
        "ocr",
        "minicap"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "dbf015f00e1e1d80a3299ac77412ba2c223b6ad6eb86836d936efa0b6cc1f673",
                "md5": "20c80059bd8b3eea5c758f75cce80786",
                "sha256": "4c2d101b04b761e0fa863ede46cc463731feabb71bbda40950b221df6c87f374"
            },
            "downloads": -1,
            "filename": "adbui-4.5.22.tar.gz",
            "has_sig": false,
            "md5_digest": "20c80059bd8b3eea5c758f75cce80786",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 34617,
            "upload_time": "2024-05-31T08:52:49",
            "upload_time_iso_8601": "2024-05-31T08:52:49.481847Z",
            "url": "https://files.pythonhosted.org/packages/db/f0/15f00e1e1d80a3299ac77412ba2c223b6ad6eb86836d936efa0b6cc1f673/adbui-4.5.22.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-31 08:52:49",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "hao1032",
    "github_project": "adbui",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "adbui"
}
        
Elapsed time: 2.92421s