V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Austin2035
V2EX  ›  分享发现

APP 自动化那些事儿:高效定位, 像解析网页一样定位 APP

  •  
  •   Austin2035 · 2020-08-30 01:54:09 +08:00 · 2371 次点击
    这是一个创建于 1548 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原文地址:

    https://www.lookcos.cn/?p=816

    前言:

    随着移动互联网的兴起,国内早已是 APP 的天下,虽然主流的大厂都有 web 端,但是不可否认,很多好数据只有 APP 端才有。

    本文只为多提供一种可能,萝卜咸菜,各有所爱。

    天下武功,为快不破:

    工欲善其事,必先利其器,对工具的选择就是对效率的选择。

    久闻 Appium 大名,但是经过上手一番才发现,并没有描述的那么美好,启动 appium 就得十几秒,偶尔还会报错、定位缓慢、操作都是重量级等等。。。

    Appium 还需要配合 Java SDK 与 Android SDK,安装安卓 SDK 甚至还得安装 Android studio (尽管也可以不安装,但是我相信,大多数教程还是教你安装)。

    那么?如题?到底能不能像解析网页一样解析 APP 页面呢?答案是:从某种意义上来说是可以的!

    道,可道:

    Appium 定位方法比较多,比较常用的有通过布局 id 定位,或者 xpath 定位。而我们如何查看 APP 当前的布局信息呢?

    方法很多,appium 自带和 Android studio 中都是用到了 UI Automator 这个工具。

    事实上,安卓系统中自带的就有 uiautomator 这个工具,我们可以利用 adb 执行它的 dump 命令导出当前的布局文件,然后利用 lxml 库分析元素位置等信息。

    小试牛刀:

    首先 window 用户可以移步至 https://adbshell.com/downloads,下载 adb 工具并配置好环境变量。
    接着跟我执行如下命令:

    
    # adb 连接安卓,( mumu 模拟器默认的地址与端口)
    
    adb connect 127.0.0.1:7555    
    
    # 利用 uiautomator 工具的 dump 命令,将当前 app 界面的布局文件导出至 sdcard 下,保存在 ui.xml 文件中
    
    adb shell uiautomator dump /sdcard/ui.xml
    
    #接着把文件导出到电脑本地
    
    adb pull /sdcard/ui.xml E:\ui
    

    打开可能会发现都在一行,不利于阅读,我们用在线工具美化一下:

    不难发现,resource-id,text 、class 这些都出来了。

    雄关漫道真如铁,而今迈步从头越:

    到了这一步熟悉了吧,祭出我们的 lxml 库来解析出我们想要的数据,取出对应元素的 bounds 值,我们就能获得该元素的坐标,进而点击它。如,bounds="[198,127][292,164]",这个 bounds 表示的是该元素的块区域坐标。

    python 使用 lxml 解析 ui.xml

    # -*- coding: utf-8 -*-
    
    from lxml import etree
    
    xml = etree.parse("ui.xml")
    soup = xml.getroot()
    res = soup.xpath('//node[@text="热榜"]')[0]
    print(res.get("text"), res.get('bounds'))
    
     #对应的 node <node index="0" text="热榜" resource-id="" class="android.widget.TextView" package="com.coolapk.market" content-desc="" checkable="false" checked="false" clickable="false" enabled="true" focusable="false" focused="false" scrollable="false" long-clickable="false" password="false" selected="false" bounds="[218,127][272,164]" /></node>
    

    这是我获取酷安首页的布局文件,下面是打印结果:

    短短几行熟悉的代码,我们就获得了 bounds 的值,也即是 热榜这个对应的坐标范围:

    通过实际查看发现,确实是在这个范围内。

    我们来写一个函数,解析它,并返回一个合法坐标

    # -*- coding: utf-8 -*-
    
    import os
    import time
    import random
    from lxml import etree
    
    os.system(r"adb connect 127.0.0.1:7555")
    os.system(r"adb shell uiautomator dump /sdcard/ui.xml")
    time.sleep(2.5)
    os.system(r"adb pull /sdcard/ui.xml E:\ui")
    
    # 解析 bounds
    def parse_bounds(bounds):
        bounds = bounds.replace("[", " ").replace(",", " ").replace("]", " ").replace("  ", " ").strip(" ").split(" ")
        x = random.randint(int(bounds[0]), int(bounds[2]))
        y = random.randint(int(bounds[1]), int(bounds[3]))
        return str(x), str(y)
    
    xml = etree.parse("ui.xml")
    soup = xml.getroot()
    res = soup.xpath('//node[@text="热榜"]')[0]
    x, y = parse_bounds(res.get('bounds'))
    # 点击
    os.system(r"adb shell input tap {0} {1}".format(x, y))
    

    上动图演示:

    结束语:

    实际的应用中还是很有用的,比如抖音此类搜索结果,不同的关键词有不同的视频量,有一些关键词我们需要扒拉几百下,而有的关键词只需要几下。

    这个时候我们就可以通过这种方式来判断当前页面是否出现了“没有更多了”诸如此类的字眼。

    看看,根据 id 、描述、text 等信息定位并不难,而且效率与稳定性更是没得说。

    本文仅作为演示,算是提供一种思路吧!

    我的博客:

    喜欢研究爬虫、web 等技术,欢迎来踩踩。
    https://www.lookcos.cn/

    7 条回复    2020-09-01 18:18:29 +08:00
    qq292382270
        1
    qq292382270  
       2020-08-30 03:11:43 +08:00
    用了四年多安卓无障碍(AccessibilityService)开发自动化了,网上有好多高度集成的自动化产品了(例如 auto.js) ,学了几天发现还是自己用 java 写原生舒服...
    itskingname
        2
    itskingname  
       2020-08-30 07:29:40 +08:00 via iPhone
    Appium 是出了名的笨重难用。你应该了解一下现代化的工具再来写文章。

    用用看 Airtest

    https://mp.weixin.qq.com/s/t4_OUPHh0qB0UV-6uGHq9g
    Austin2035
        3
    Austin2035  
    OP
       2020-08-30 09:04:00 +08:00 via iPhone
    @itskingname 你完整看一下文章再喷大哥,
    我只是多提供一种思路。
    你的公众号我有关注,没少洗稿!
    lzlee
        4
    lzlee  
       2020-08-30 09:50:08 +08:00
    app 内嵌 h5 方便定位吗
    Austin2035
        5
    Austin2035  
    OP
       2020-08-30 21:02:12 +08:00 via iPhone
    @lzlee 纸上得来终觉浅,绝知此事要躬行
    ttimasdf
        6
    ttimasdf  
       2020-09-01 18:16:16 +08:00
    楼主这个办法的确不用装一大堆东西,但实际进行应用分析的话,各种环境的安装还是必不可少的吧,合适的工具对提高分析效率也有很大的帮助。比如 Appium 自己也带了一个类似 Airtest 的 GUI 工具,我前一阵子也写过一个文章分享使用体验,还是蛮好用的(当然,当时我也不知道 Airtest,哈哈哈)

    https://blog.rabit.pw/2020/appium-android-app-automation/
    ttimasdf
        7
    ttimasdf  
       2020-09-01 18:18:29 +08:00
    @lzlee h5 就更好分析了呀,既然走 http 协议,抓包获取页面 html 内容,或者获取页面 URL 从电脑打开,和爬 web 页面的技巧是一样的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3626 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 11:03 · PVG 19:03 · LAX 03:03 · JFK 06:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.