美文网首页
6. 多设备管理库 ATXServer2

6. 多设备管理库 ATXServer2

作者: BeautifulSoulpy | 来源:发表于2020-12-17 22:14 被阅读0次

参考:

  1. ATX 安卓设备集群管理 atx-server
  2. 利器 | ATXServer2 手机设备管理平台重装上阵

6-1 atxserver2库介绍

1. atxserver

atx-agent运行在手机的内部,为手机增加了远程控制,自动化的功能。atx-server最重要的功能,是将atx-agent汇总到一个网页上展示,并提供一个API可以获取所有设备的列表。


2. atxserver2

atx-server 在使用的过程中不断的优化,当有一天最终优化不下去了。于是开始了 atxserver2[2] 的筹备计划。这个项目 2019/01/15 号开始开发的,目前开发了大概 3 个月了。已经比较稳定了。以前的服务端是用的 Go+RethinkDB, 现在则是用的 Python3+NodeJS+RethinkDB。

架构图

主要希望提供的 Features(不过有些完成了,有些没完成)
• 使用 Python 重写服务端和客户端(Go 语言写服务端速度有点慢,没有 Python 弄的快)
• 网页控制手机提供更全的功能(原有的 atx-server 功能非常的少,只有操作手机和一个手机 shell 终端)
• 支持 USB 设备的接入 (主要是为了提高稳定性)
• 支持 iOS 设备 (这个功能的呼声一直很高)
• 全面的 REST API 文档。(原来可能有,但是不全)
• 支持 WIFI 设备的接入(这个暂时还没搞完,不过很快了)
• 支持跨网段的设备接入 (假如有这个功能的话,感觉家里闲置的手机也能派上用场了)

支持多设备管理 支持手动操作 支持应用安装和卸载

6-2 atxserver2通过pip安装部署

因为arxserver2是基于rethinkdb数据库,先安装rethinkdb
https://rethinkdb.com/docs/install/

1. rethinkdb安装
1.1 Linux下 rethinkdb安装

https://github.com/srh/rethinkdb/releases/tag/v2.3.6.srh.1

下载对应的版本
user1@imooc:~/data$ ll -r
总用量 157700
-rwxrw-rw-  1 user1 user1 10291396 12月  1 12:31 rethinkdb_2.3.6.srh.1.0bionic_amd64.deb*

user1@imooc:~/data$ sudo dpkg -i rethinkdb_2.3.6.srh.1.0bionic_amd64.deb

# 启动好 rethinkdb
user1@imooc:~$ rethinkdb
Running rethinkdb 2.3.6.srh.1~0bionic (CLANG 6.0.0 (tags/RELEASE_600/final))...
Running on Linux 5.4.0-56-generic x86_64
Loading data from directory /home/user1/rethinkdb_data
Listening for intracluster connections on port 29015
Listening for client driver connections on port 28015
Listening for administrative HTTP connections on port 8080
Listening on cluster addresses: 127.0.0.1, ::1
Listening on driver addresses: 127.0.0.1, ::1
Listening on http addresses: 127.0.0.1, ::1
To fully expose RethinkDB on the network, bind to all addresses by running rethinkdb with the `--bind all` command line option.
Server ready, "imooc_p17" 8b933881-bfe0-4a75-9051-c99a3a47704e
A newer version of the RethinkDB server is available: 2.4.0. You can read the changelog at <https://github.com/rethinkdb/rethinkdb/releases>.
1.2 win10 下 rethinkdb安装

参考:windows10搭建atxserver2 移动设备管理平台

https://github.com/srh/rethinkdb/releases/
https://github.com/openatx/atxserver2-android-provider
下载好这两个文件

下载好
ipconfig
Windows IP 配置


以太网适配器 以太网:

   连接特定的 DNS 后缀 . . . . . . . : DHCP HOST
   本地链接 IPv6 地址. . . . . . . . : fe80::183e:9e88:d02b:4977%18
   IPv4 地址 . . . . . . . . . . . . : 192.168.0.104
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 192.168.0.1

1.安装部署rethindb
解压文件双击运行,效果如下

Initializing directory F:\soft\rethinkdb-v2.4.0-srh-win-1-Release_x64\rethinkdb_data
Running rethinkdb 2.3.2-windows-beta-545-g85e842 (MSC 190024225)...
Running on 6.2.9200 (Windows 8, Server 2012)
Loading data from directory F:\soft\rethinkdb-v2.4.0-srh-win-1-Release_x64\rethinkdb_data
Listening for intracluster connections on port 29015
Listening for client driver connections on port 28015
Listening for administrative HTTP connections on port 8080
Listening on cluster address: 127.0.0.1
Listening on driver address: 127.0.0.1
Listening on http address: 127.0.0.1
To fully expose RethinkDB on the network, bind to all addresses by running rethinkdb with the `--bind all` command line option.
Server ready, "DESKTOP_FQ3N661_mi4" 92c34b13-097c-4dfd-a68d-bbf6aa399cf4
Someone asked for the nonwhitelisted file "/announce".  If this should be accessible, add it to the static web assets.
Someone asked for the nonwhitelisted file "/announce".  If this should be accessible, add it to the static web assets.



2.安装atxserver2

先将代码clone到本地
git clone https://github.com/openatx/atxserver2.git
进入atxserver2目录,使用如下方法安装依赖

pip install -r requirements.txt

安装成功后,启动rethinkdb,然后使用以下方式启动:

# 启动方式,这也是最简单的启动方法
python3 main.py

# 指定认证方式
python3 main.py --auth simple # 默认是一个非常simple的认证,输入邮箱就可以
python3 main.py --auth openid # 网易内部使用
# 其他的认证方式还有待添加,非常欢迎PR

# 设置监听端口
python3 main.py --port 4000 # 默认监听的就是这个地址

# 默认支持运行在Nginx下,支持 X-Real-Ip/X-Forwarded-For
# 如果不需要可以通过 --no-xheaders 关闭该功能

启动之后,浏览器上打开 http://localhost:4000,完成登录认证之后就可以顺利的看到设备列表页了。不过目前还是空的,什么都没有

3.接入安卓设备
接入Android设备,需要用到另一个项目 atxserver2-android-provider

因为平台是windows10,所以我们使用源码部署。项目依赖:Python3.6+NodeJSGit-LFS

首先安装Git-LFS https://git-lfs.github.com/

git clone https://github.com/openatx/atxserver2-android-provider.git

cd atxserver2-android-provider
git lfs install
git lfs push

pip install -r requirements.txt

执行成功后,直接在 atxserver2-android-provider目录安装依赖,然后直接启动

python main.py --server localhost:4000

坑1,注意!!!
若git clone不下来只能自己去github上手动下压缩包,解压即可
坑2,注意!!!
出错原因:要上传的目录没有初始化;
解决办法:git init 再 git lfs install------------> 用于解决 github 不能上传100M文件的限制

E:\atxserver2-android-provider-master> git lfs install
Error: Failed to call git rev-parse --git-dir --show-toplevel: "fatal: not a git repository (or any of the parent directories): .git\n"
Git LFS initialized.

坑3,注意!!!
git lfs push如果报错,就手动去 https://github.com/openatx/atxserver2-android-provider/tree/master/vendor 中将所有apk文件以及zip包手动下载下来并放入

2. 安装atxserver2

https://github.com/openatx/atxserver2

要先启动rethinkdb数据库

sudo apt-get install git

user1@imooc:~$ git clone https://github.com/openatx/atxserver2.git
正克隆到 'atxserver2'...
remote: Enumerating objects: 1050, done.
remote: Total 1050 (delta 0), reused 0 (delta 0), pack-reused 1050
接收对象中: 100% (1050/1050), 1.61 MiB | 1.17 MiB/s, 完成.
处理 delta 中: 100% (744/744), 完成.

user1@imooc:~/atxserver2$ source activate venv
(venv) user1@imooc:~/atxserver2$ pip install -r requirements.txt -i https://pypi.douban.com/simple

(venv) user1@imooc:~/atxserver2$ python main.py 
Namespace(auth='simple', auth_conf_file=None, debug=False, no_xheaders=False, port=4000)
[I 201217 11:20:54 main:70] listen on port http://192.168.0.103:4000

http://192.168.0.103:4000/devices

设备列表

要连接安卓设备,需要一些项目支持


user1@imooc:~$ sudo apt install curl
user1@imooc:~$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
user1@imooc:~$ sudo apt-get install -y nodejs

user1@imooc:~$ nodejs -V
nodejs: bad option: -V
user1@imooc:~$ nodejs -v
v8.17.0
user1@imooc:~$ npm -v
6.13.4

user1@imooc:~$ git clone https://github.com/openatx/atxserver2-android-provider
user1@imooc:~$ cd atxserver2-android-provider/
user1@imooc:~/atxserver2-android-provider$ ls
asyncadb.py           DEVELOP.md       Dockerfile      LICENSE       README.md         settings.py
build-docker-push.sh  device_names.py  heartbeat.py    main.py       requirements.txt  tcpproxy.js
core                  device.py        install-adb.sh  package.json  run.sh   

user1@imooc:~/atxserver2-android-provider$ npm install

user1@imooc:~/atxserver2-android-provider$ source activate venv
(venv) user1@imooc:~/atxserver2-android-provider$ ll

(venv) user1@imooc:~/atxserver2-android-provider$ pip install -r requirements.txt -i https://pypi.douban.com/simple
(venv) user1@imooc:~/atxserver2-android-provider$ pip install humanize -i https://pypi.douban.com/simple 


(venv) user1@imooc:~/atxserver2-android-provider$ python main.py --server http://192.168.0.103:4000
[I 201217 11:43:34 main:299] Owner: None
[I 201217 11:43:34 main:314] ProviderURL: http://192.168.0.103:3500
>>> Bundle atx-agent verison: 0.9.5
Downloading atx-agent-386.tar.gz 4453385 / 4453385 [Done]
Downloading atx-agent-amd64.tar.gz 4632088 / 4632088 [Done]
Downloading atx-agent-armv6.tar.gz 4353956 / 4353956 [Done]
Downloading atx-agent-armv7.tar.gz 4348419 / 4348419 [Done]
>>> Zip created vendor/atx-agent-0.9.5.zip
>>> app-uiautomator.apk verison: 2.3.1
Downloading app-uiautomator.apk 2165152 / 2165152 [Done]
>>> app-uiautomator-test.apk verison: 2.3.1
Downloading app-uiautomator-test.apk 1212676 / 1212676 [Done]
Downloading WhatsInput-1.0.apk 265471 / 265471 [Done]
Downloading stf-binaries-0.2.1.zip 5400734 / 5400734 [Done]
[I 201217 11:43:51 heartbeat:139] WS receive: {"success": true, "id": "145363d4-401a-11eb-b4a8-000c29fce5eb"}
[D 201217 11:43:51 main:234] DeviceEvent(present=True, serial='192.168.0.101:5555', status='device')
[D 201217 11:43:51 main:238] Skip remote device: DeviceEvent(present=True, serial='192.168.0.101:5555', status='device')


user1@imooc:~/atxserver2-android-provider$ adb kill-server
user1@imooc:~/atxserver2-android-provider$ adb devices
List of devices attached

user1@imooc:~/atxserver2-android-provider$ adb connect 192.168.0.101
connected to 192.168.0.101:5555
user1@imooc:~/atxserver2-android-provider$ adb devices
List of devices attached
192.168.0.101:5555  device

该镜像会把所有必要的资源 (atx-uiautomator.apk, minicap, minitouch, atx-agent) 全部推送到手机上。 一切就绪后,你可以进行远程真机的操作了。

前4个在初始化的时候就已经安装好了, whatsinput-apk 会被安装到手机中;

6-3 atxserver2多设备管理库的使用

atxserver2不支持安卓虚拟机,最好使用真机


1. RethinkDB

RethinkDB最早是作为一个对SSD进行专门优化的MySQL存储引擎出现的,其特点在于对SSD的充分利用。而目前RethinkDB已经脱离MySQL成为一个独立的存储。
RethinkDB的优化没有mongodb好,比之慢3倍;


RethinkDB的特点:

  • 随CPU个数线程扩展
  • SSD上速度快十倍
  • 节省内存空间
  • 断电后及时恢复
  • 细化的持久性控制
  • 支持上万的并发连接数
  • 支持裸盘设备,多磁盘上自动数据分区
  • 支持多平台部署;支持图形界面
user1@imooc:/etc/rethinkdb$ cd /etc/rethinkdb/
user1@imooc:/etc/rethinkdb$ sudo cp default.conf.sample default.conf
user1@imooc:/etc/rethinkdb$ ls
default.conf  default.conf.sample  instances.d

user1@imooc:/etc/rethinkdb$ sudo nano default.conf

# 修改一个设置(绑定所有端口)
bind=0.0.0.0

user1@imooc:/etc/rethinkdb$ sudo cp default.conf instances.d/
user1@imooc:/etc/rethinkdb$ cd instances.d/
user1@imooc:/etc/rethinkdb/instances.d$ ll
总用量 12
drwxr-xr-x 2 root root 4096 12月 17 20:50 ./
drwxr-xr-x 3 root root 4096 12月 17 20:48 ../
-rw-r--r-- 1 root root 2881 12月 17 20:50 default.conf

# 加载配置文件
user1@imooc:~/atxserver2-android-provider$ rethinkdb --config-file /etc/rethinkdb/instances.d/default.conf 

Loading data from directory /home/user1/atxserver2-android-provider/rethinkdb_data
Listening for intracluster connections on port 29015
Listening for client driver connections on port 28015
Listening for administrative HTTP connections on port 8080
Listening on cluster addresses: 127.0.0.1, 192.168.0.103, ::1, fe80::20c:29ff:fefc:e5eb%2
Listening on driver addresses: 127.0.0.1, 192.168.0.103, ::1, fe80::20c:29ff:fefc:e5eb%2
Listening on http addresses: 127.0.0.1, 192.168.0.103, ::1, fe80::20c:29ff:fefc:e5eb%2

默认端口8080
http://192.168.0.103:8080/


Tables数据库中包含了3个表devices/groups/users

查询数据库

数据库查询的常用命令


数据库 表的分组,让部分人可见;

设备信息都会存储到数据库;


2. ATXserver2 设备控制

点击设备,进入到设备管理页面


打开浏览器 网页

快捷入口

命令行操作

常见命令
安装APP

文件管理、截图、应用管理

两台手机
ATXServer2 最大支持80台手机并发抓取数据

6-4 实现多任务端app应用数据抓取系统

1. 多任务端app应用数据抓取系统

实现多任务端app应用数据抓取系统采用的是多进程;用Python的多进程控制多个手机设备,

所有的设备都在一个无线路由器下 连接,mitmdump和atxserver2 在同一个电脑上没使用同一个IP =172.20.10.3; 多台手机设备处于同一个网段下;
采用atxserver2 来监控两台手机;
通过U2来实现模拟和点击手机操作;
最终,通过mitmdump 来解析抖音短视频数据;

不同的手机 打开APP 权限申请的提示界面是不同的


先判断ubuntu中连接了多少个设备

# 1. adb
adb devices

# 2.subprocess adb devices

# handle_douyin.py
import uiautomator2 as u2
import time
import adbutils, multiprocessing

class Douyin(object):
    def __init__(self, serial="192.168.0.101"):
        # 连接
        self.d = u2.connect(serial)
        # 调用方法
        self.start_app()        # 启动
        self.handle_watcher()  # 监控器
        self.size = self.get_windowsize()
        # 获取初始时间
        self.t0 = time.perf_counter()

    def start_app(self):
        self.d.app_start(package_name="com.ss.android.ugc.aweme")

    def stop_app(self):
        """退出逻辑"""
        self.d.watcher.stop()
        self.d.app_stop("com.ss.android.ugc.aweme")
        self.d.app_clear("com.ss.android.ugc.aweme")

    def stop_time(self):
        if time.perf_counter() - self.t0 > 360:  # 3600s
            return True

    def handle_watcher(self):
        # 通知权限
        self.d.watcher.when('//*[@resource-id="com.ss.android.ugc.aweme:id/a4r"]').click()
        # 发现滑动查看更多
        self.d.watcher.when('//*[@text="滑动查看更多"]').click()
        self.d.watcher.when('//*[@text="快速进入TA的个人中心"]').click()
        # 给乐视手机使用的监控器
        self.d.watcher.when('//[@text="允许"]').click()

        self.d.watcher.start(interval=1)

    def get_windowsize(self):
        return self.d.window_size()

    def handle_swipe(self):
        x1 = int(self.size[0] * 0.5)
        y1 = int(self.size[1] * 0.9)
        y2 = int(self.size[1] * 0.15)
        self.d.swipe(x1, y1, x1, y2)


    def swipe_douyin(self):
        '''滑动抖音短视频 点击视频发布者头像的操作'''
        # 判断是否正常进入抖音界面
        if self.d(resourceId="com.ss.android.ugc.aweme:id/yy", text="我").exists(timeout=20):
            while True:
                if self.stop_time():
                    self.stop_app()
                    return

                # 查看 是不是正常的发布者(不是广告)
                if self.d(resourceId="com.ss.android.ugc.aweme:id/u0").exists:
                    # 是不是正常的 发布者,点击头像
                    self.d(resourceId="com.ss.android.ugc.aweme:id/tw").click()
                    # 返回
                    self.d(resourceId="com.ss.android.ugc.aweme:id/et").click()
                # 可能是做广告;
                else:
                    self.handle_swipe()

                # 判断是否正常进入抖音界面
                if self.d(resourceId="com.ss.android.ugc.aweme:id/yy", text="我").exists and self.d(resourceId="com.ss.android.ugc.aweme:id/u0").exists:
                    # 滑动: 由下向上滑动;
                    self.handle_swipe()

def get_devices():
    # 获取当前操作系统中所连接的移动设备 serial num
    return [d.serial for d in adbutils.adb.device_list()]

def handle_device(serial):
    d = Douyin(serial)
    d.swipe_douyin()

def main():
    # 多进程启动u2去滑动移动设备;
    for i in range(len(get_devices())):
        serial = get_devices()[int(i)]
        p = multiprocessing.Process(target=handle_device, args=(serial,))
        p.start()

if __name__ == '__main__':
    print(get_devices())

#-------------------------------
['98895a353059414c5a', '192.168.0.101:5555']   # 2个设备

2.mitmdump 解析数据

1.要保证安装了证书
2.手机都使用了ubuntu的代理IP=192.168.0.103 8889

(venv) user1@imooc:~/u2_project/douyin$ mitmdump -s decode_douyin.py -p 8889
Loading script decode_douyin.py
Proxy server listening at http://*:8889
# handle_douyin.py
import uiautomator2 as u2
import time
import adbutils, multiprocessing

class Douyin(object):
    def __init__(self, serial="192.168.0.101"):
        # 连接
        self.d = u2.connect(serial)
        # 调用方法
        self.start_app()        # 启动
        self.handle_watcher()  # 监控器
        self.size = self.get_windowsize()
        # 获取初始时间
        self.t0 = time.perf_counter()

    def start_app(self):
        self.d.app_start(package_name="com.ss.android.ugc.aweme")

    def stop_app(self):
        """退出逻辑"""
        self.d.watcher.stop()
        self.d.app_stop("com.ss.android.ugc.aweme")
        self.d.app_clear("com.ss.android.ugc.aweme")

    def stop_time(self):
        if time.perf_counter() - self.t0 > 360:  # 3600s
            return True

    def handle_watcher(self):
        # 通知权限
        self.d.watcher.when('//*[@resource-id="com.ss.android.ugc.aweme:id/a4r"]').click()
        # 发现滑动查看更多
        self.d.watcher.when('//*[@text="滑动查看更多"]').click()
        self.d.watcher.when('//*[@text="快速进入TA的个人中心"]').click()
        # 给乐视手机使用的监控器
        self.d.watcher.when('//[@text="允许"]').click()

        self.d.watcher.start(interval=1)

    def get_windowsize(self):
        return self.d.window_size()

    def handle_swipe(self):
        x1 = int(self.size[0] * 0.5)
        y1 = int(self.size[1] * 0.9)
        y2 = int(self.size[1] * 0.15)
        self.d.swipe(x1, y1, x1, y2)


    def swipe_douyin(self):
        '''滑动抖音短视频 点击视频发布者头像的操作'''
        # 判断是否正常进入抖音界面
        if self.d(resourceId="com.ss.android.ugc.aweme:id/yy", text="我").exists(timeout=20):
            while True:
                if self.stop_time():
                    self.stop_app()
                    return

                # 查看 是不是正常的发布者(不是广告)
                if self.d(resourceId="com.ss.android.ugc.aweme:id/u0").exists:
                    # 是不是正常的 发布者,点击头像
                    self.d(resourceId="com.ss.android.ugc.aweme:id/tw").click()
                    # 返回
                    self.d(resourceId="com.ss.android.ugc.aweme:id/et").click()
                # 可能是做广告;
                else:
                    self.handle_swipe()

                # 判断是否正常进入抖音界面
                if self.d(resourceId="com.ss.android.ugc.aweme:id/yy", text="我").exists and self.d(resourceId="com.ss.android.ugc.aweme:id/u0").exists:
                    # 滑动: 由下向上滑动;
                    self.handle_swipe()

def get_devices():
    # 获取当前操作系统中所连接的移动设备 serial num
    return [d.serial for d in adbutils.adb.device_list()]

def handle_device(serial):
    d = Douyin(serial)
    d.swipe_douyin()

def main():
    # 多进程启动u2去滑动移动设备;
    for i in range(len(get_devices())):
        serial = get_devices()[int(i)]
        p = multiprocessing.Process(target=handle_device, args=(serial,))
        p.start()

if __name__ == '__main__':
    mian()




3. ATXServer2 监控APP

打开按钮,就可以动态的查看手机的界面;


相关文章

网友评论

      本文标题:6. 多设备管理库 ATXServer2

      本文链接:https://www.haomeiwen.com/subject/yugagktx.html