Appium和Python實現螞蟻森林自動化收取能量

胡峻崢發表於2021-07-24

 

準備環境

  Window10系統

  Appium1.21.0

  AndroidSDK r24.1.1

  Python3.7.5

  支付寶apk檔案

檢視支付寶apk包資訊

使用android sdk aapt命令檢視支付寶apk包資訊,後面會用到,如下。

Android Asset Packaging Tool

Usage:
 aapt l[ist] [-v] [-a] file.{zip,jar,apk}
   List contents of Zip-compatible archive.

 aapt d[ump] [--values] [--include-meta-data] WHAT file.{apk} [asset [asset ...]]
   strings          Print the contents of the resource table string pool in the APK.
   badging          Print the label and icon for the app declared in APK.
   permissions      Print the permissions from the APK.
   resources        Print the resource table from the APK.
   configurations   Print the configurations in the APK.
   xmltree          Print the compiled xmls in the given assets.
   xmlstrings       Print the strings of the given compiled xml assets.

D:\android-sdk-windows\build-tools\29.0.0> .\aapt.exe dump badging C:\Users\XXX\Downloads\alipay_wap_main.apk

輸出結果如下:
package: name='com.eg.android.AlipayGphone'
versionCode='410'
versionName='10.2.26.9000'
compileSdkVersion='29'
compileSdkVersionCodename='10'
install-location:'auto'
sdkVersion:'18'
targetSdkVersion:'29'
launchable-activity: name='com.eg.android.AlipayGphone.AlipayLogin'

檢測裝置是否連線

一開始想用模擬器(如夜神模擬器)進行自動化,後來發現支付寶在模擬器裡執行特別卡,最終決定使用真機了。這裡使用android sdk的adb工具檢測手機裝置是否連線正常,如下。如果看不到連線資訊或者顯示unauthorized的,請開啟手機的USB除錯許可權,也有可能開啟開發者模式呦。

準備知識

pip install 預設安裝路徑修改

Appium工作原理

Appium使用Python執行appium測試的例項

安裝自動化工具包

pip install Appium-Python-Client --user

An extension library for adding Selenium 3.0 draft and Mobile JSON Wire Protocol Specification draft functionality to the Python language bindings, for use with the mobile testing framework Appium.

pip install pytest --user

The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.

安裝包的時候加上引數--user 包就會自動安裝到自定義路徑下面

啟動Appium服務端

開啟新會話定位畫面元素

 

{
  "deviceName": "Alipay-Test",
  "platformName": "Android",
  "platformVersion": "10",
  "appActivity": "com.eg.android.AlipayGphone.AlipayLogin",
  "appPackage": "com.eg.android.AlipayGphone",
  "noReset": true,
  "fullReset": false
}

編寫python指令碼

知道如何定位支付寶介面的元素後,開始編寫python自動化執行指令碼。大體分為如下幾個步驟。

初始化客戶端

def setUp(self):
    desired_caps = {}
    desired_caps['platformName'] = 'Android'
    desired_caps['platformVersion'] = '10'
    desired_caps['deviceName'] = 'Alipay'
    desired_caps['appActivity'] = 'com.eg.android.AlipayGphone.AlipayLogin'
    desired_caps['appPackage'] = 'com.eg.android.AlipayGphone'
    desired_caps['noReset'] = True
    desired_caps['fullReset'] = False

    self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

客戶端初始化後會自動啟動支付寶APP,注意noReset和fullReset引數的設定。

If noReset is set to TRUE, the app data will NOT be cleared before this session starts.
If fullReset is set to true, the app will get uninstalled and all data will be cleared.

解鎖手機

def unlocked(self):
    sz = self.getSize();
    x1 = int(sz[0] * 0.10)      #x座標
    y1 = int(sz[1] * 0.95)      #起始y座標
    y2 = int(sz[1] * 0.15)      #終點y座標
    self.driver.swipe(x1, y1, x1, y2, 1000)
    sleep(1)
    try:
        self.driver.find_element_by_id('com.android.systemui:id/vivo_pin_keyboard')
        for k in [5,1,2,9,9,9]:
            self.driver.find_element_by_id('com.android.systemui:id/VivoPinkey%d' % k).click()
        print('手機解鎖成功...')
    except NoSuchElementException:
        print('手機已解鎖或解鎖失敗')

進入螞蟻森林

def entry_ant_forest(self):
  try:
      sleep(2)
      # 點選螞蟻森林icon
      self.driver.find_element_by_android_uiautomator('new UiSelector().text("螞蟻森林")').click()
  except NoSuchElementException:
      # 異常回到首頁重試
      self.driver.back()
      sleep(2)
      # 點選支付寶icon
      self.driver.find_element_by_android_uiautomator('new UiSelector().text("支付寶")').click()
      sleep(2)
      # 點選螞蟻森林icon
      self.driver.find_element_by_android_uiautomator('new UiSelector().text("螞蟻森林")').click()

按理說進入螞蟻森林直接模擬點選“螞蟻森林”icon就可以了,但是偶爾會丟擲NoSuchElementException異常。也就是Appium在切換activity後導致元素無法定位,如果手機不鎖屏不會發生這種情況(可以在開發者模式中指定),鎖屏解鎖後切換到支付寶的activity後偶爾會出現這種情況。沒有找到太好的解決方法,發生異常時使手機介面返回到首頁,然後點選支付寶重新進入,最後點選螞蟻森林進入。

搜尋能量

def search_energy(self):
    # 點選找能量
    self.driver.tap([(1000, 1520), (1080, 1580)], 1000)
    sleep(3)
    try:
        self.driver.find_element_by_android_uiautomator('new UiSelector().textContains("好友能量都收完了")')
    except NoSuchElementException:
        try:
            self.driver.find_element_by_android_uiautomator('new UiSelector().textContains("返回我的森林")')
        except NoSuchElementException:
            pass
        else:
            print('全部好友能量收取完畢...')
            return
            
        # 收取好友能量
        self.collect_energy()
        # 繼續找能量
        self.search_energy()
    else:
        print('全部好友能量收取完畢...')

點選“找能量”功能自動定位到有能量偷取的好友介面。如果介面中有“好友能量都收完了”或者“返回我的森林”相關字樣,結束查詢,否則開始收取好友能量。

收取好友能量

def collect_energy(self):
    name = ''
    try:
        name = self.driver.find_element_by_id('com.alipay.mobile.nebula:id/h5_tv_title').text
    except NoSuchElementException:
        pass
    
    print('開始收取%s的能量...' % name)
    
    # 獲取手機螢幕寬高
    sz = self.getSize();
    width = sz[0]
    height = sz[1]
    
    # 能量球可能出現的區域座標
    start_x = 110
    end_x = 940
    start_y = 460
    end_y = 880
    for i in range(start_y, end_y, 80):
        for j in range(start_x,end_x, 80):
            try:
                self.driver.find_element_by_android_uiautomator('new UiSelector().textContains("關閉")').click()
                sleep(1)
            except NoSuchElementException:
                pass
            tap_x1 = int((int(j) / width) * width)
            tap_y1 = int((int(i) / height) * height)
            # 點選指定座標
            self.driver.tap([(tap_x1, tap_y1), (tap_x1, tap_y1)], 1000)
            
    print('結束收取%s的能量...' % name)

首先獲取當前頁面的“com.alipay.mobile.nebula:id/h5_tv_title”元素,代表好友的名字;因為螞蟻森林現在不能定位能量球元素了,所以要在能量球可能出現的方塊區域按照一定的座標步長模擬點選進行能量偷取。上面的方案中,規定的能量球可能出現的區域為[(110,460),(940,880)],這個座標可以根據實際的機型進行修改,可以通過Appium座標定位判斷出矩形區域,如下。

 

還要一個點需要注意的,點選的時候可能會出現裝飾樹和掛件的展示,如下圖所示。這時候需要在介面中查詢“關閉”元素,然後click事件關閉就行了。

演示效果

如果效果感覺還不錯的話,那就關注一下微信公眾號(請掃下方二維碼),回覆“螞蟻森林”獲取完整程式碼吧。

 

相關文章