python+ADB实现手机控制(2021淘宝的喵糖活动自动点击)

python+ADB实现手机控制(2021淘宝的喵糖活动自动点击)

背景

双十一 TaoBao的活动太折磨人了,要一个一个点击进去浏览,等待若干秒,不如直接写个小程序挂机吧!!!

环境

ADB(Android 调试桥)

ADB提供了一组你可以控制调试安卓手机的命令,理解起来并不难。有了ADB,你可以把自己对手机的操作替换成命令行。

ADB的官网下载连接:https://editor.csdn.net/md?not_checkout=1&articleId=120978183。

ADB下载后解压,不能直接点击EXE文件运行,需要通过命令行的方式打开。请添加图片描述通过CMD方式打开ADB,记得将目录切换到adb.exe在的路径。输入adb,检查是否正确执行:

请添加图片描述为了python能够直接调用adb,需要添加环境变量。
添加环境变量:与所有田间环境变量的方法一样,在高级系统设置里添加一条新的环境变量,名称为“adb”,路径为adb的解压路径,然后在PATH变量中,新增一条路径。

请添加图片描述

python环境

这个右手就行吧

手机环境

  • 打开开发者模式
  • 打开USB中允许模拟点击,红米K20如下图:

请添加图片描述
-tips:如果不打开,在执行adb命令时,会报如下错误:

请添加图片描述错误信息:

java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission
        at android.os.Parcel.createExceptionOrNull(Parcel.java:2376)
        at android.os.Parcel.createException(Parcel.java:2360)
        at android.os.Parcel.readException(Parcel.java:2343)
        at android.os.Parcel.readException(Parcel.java:2285)
        at android.hardware.input.IInputManager$Stub$Proxy.injectInputEvent(IInputManager.java:1012)
        at android.hardware.input.InputManager.injectInputEvent(InputManager.java:907)
        at com.android.commands.input.Input.injectKeyEvent(Input.java:355)
        at com.android.commands.input.Input.access$100(Input.java:41)
        at com.android.commands.input.Input$InputKeyEvent.sendKeyEvent(Input.java:203)
        at com.android.commands.input.Input$InputKeyEvent.run(Input.java:190)
        at com.android.commands.input.Input.onRun(Input.java:107)
        at com.android.internal.os.BaseCommand.run(BaseCommand.java:60)
        at com.android.commands.input.Input.main(Input.java:71)
        at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
        at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:463)
Caused by: android.os.RemoteException: Remote stack trace:
        at com.android.server.input.InputManagerService.injectInputEventInternal(InputManagerService.java:812)
        at com.android.server.input.InputManagerService.injectInputEvent(InputManagerService.java:786)
        at android.hardware.input.IInputManager$Stub.onTransact(IInputManager.java:459)
        at android.os.Binder.execTransactInternal(Binder.java:1157)
        at android.os.Binder.execTransact(Binder.java:1126)

简单程序

实现逻辑:打开淘宝应用,找到想要点击的位置(可以通过UI Automator Viewer获得准确的位置,也可以自己简单算一下,adb默认,手机左上角是(0,0),右下角是(x_max, y_max))
获取淘宝应用名称

adb shell dumpsys window w |findstr \/ |findstr name=

实现效果:
请添加图片描述
主要用到的adb命令

  1. adb shell am start -n 应用名称 : 打开某一应用
  2. adb shell input tap x y : 模拟点击某一点
  3. adb shell input keyevent : 模拟点击某个按键

很简单的一个示例:

import os
import time

if __name__ == "__main__":
    #get into taobao app
    os.system('adb shell am start -n com.taobao.taobao/com.taobao.tao.TBMainActivity')
    # delay to imitate human
    time.sleep(3)
    os.system('adb shell input tap 1000 1300')
    time.sleep(3)
    # click into mission page
    os.system('adb shell input tap 1000 1800')
    time.sleep(3)
    # loop to get all candies
    for i in range(30):
        # click into specific mission page
        os.system('adb shell input tap 1000 1600') # third line
        time.sleep(20)
        # back to mission page
        os.system('adb shell input keyevent 4')
        time.sleep(3)
    # use up candies
    for i in range(18):
        time.sleep(5)
        os.system('adb shell input tap 500 1800')