淺談如何使用Python控制手機(jī)(二)
1. 序言
每年淘寶雙十一的時(shí)候,總是要刷各種各樣的瀏覽頁(yè)面,收集能量或者喵幣或者什么。
那既然如此,我就總想著,能否通過(guò)Python自動(dòng)調(diào)用的方式來(lái)刷網(wǎng)頁(yè)。
2. 前置工作
本文是基于使用Python控制手機(jī)(一),默認(rèn)已經(jīng)安裝了ADB并配置了環(huán)境變量,安裝了Python環(huán)境,且在Python中安裝了uiautomator2和weditor等包。
3. 打開APP
當(dāng)我們使用uiautomator2包來(lái)打開某個(gè)APP時(shí),可以通過(guò)點(diǎn)擊屏幕特殊位置的方式來(lái)實(shí)現(xiàn)。但是其中存在的問(wèn)題便是,可能由于我們APP圖標(biāo)的移動(dòng),而使得程序無(wú)法運(yùn)行。健壯性和通用性不高。
其實(shí)在uiautomator2這個(gè)包中,提供了一種可以通過(guò)APP包名就可以打開特定APP的方式,例如打開和關(guān)閉淘寶。
import uiautomator2 as u2 import time d = u2.connect() # 連接設(shè)備 d.app_start("com.taobao.taobao") # 打開淘寶 time.sleep(10) # 等待10秒鐘 d.app_stop("com.taobao.taobao") # 關(guān)閉淘寶
再比如打開和關(guān)閉微信:
import uiautomator2 as u2 import time d = u2.connect() # 連接設(shè)備 d.app_start("com.tencent.mm") # 打開微信 time.sleep(10) # 等待10秒鐘 d.app_stop("com.tencent.mm") # 關(guān)閉微信
4. 獲取APP的包名
有的時(shí)候,我們是不太清楚一個(gè)APP的包名的,這時(shí)我們可以通過(guò)打印設(shè)備當(dāng)前信息的方式來(lái)獲取APP的包名。首先我們需要將要獲取的APP打開,并且保持在手機(jī)最前臺(tái)
執(zhí)行代碼:
import uiautomator2 as u2 import time d = u2.connect() # 連接設(shè)備 print(d.info) # 打印設(shè)備信息
輸出結(jié)果如下:
{'currentPackageName': 'com.taobao.taobao', 'displayHeight': 2111, 'displayRotation': 0, 'displaySizeDpX': 393, 'displaySizeDpY': 851, 'displayWidth': 1080, 'productName': 'cannon', 'screenOn': True, 'sdkInt': 29, 'naturalOrientation': True}
Process finished with exit code 0
在所打印的Json鍵值對(duì)中,鍵currentPackageName對(duì)應(yīng)的值,即為此時(shí)正在最前臺(tái)的APP的包名,上述結(jié)果操作時(shí),正在最前的APP為淘寶。
5. 打開特定頁(yè)面
一般來(lái)說(shuō),如果頁(yè)面切換按鈕含有特定文字,我們直接通過(guò)文字進(jìn)行定位是最方便的,也是最準(zhǔn)確的,比如打開微信朋友圈:
import uiautomator2 as u2 import time d = u2.connect() # 連接設(shè)備 d.app_start("com.tencent.mm") # 打開微信 time.sleep(2) # 等待2秒鐘 d(text='發(fā)現(xiàn)').click() # 點(diǎn)擊文字為“發(fā)現(xiàn)”的控件 time.sleep(2) # 等待2秒鐘 d(text='朋友圈').click() # 點(diǎn)擊文字為“朋友圈”的控件
因?yàn)榭赡艽嬖诘模珹PP的加載時(shí)間和對(duì)點(diǎn)擊操作的響應(yīng)時(shí)間,盡量在每次點(diǎn)擊操作之后,為APP和手機(jī)留有足夠的反應(yīng)時(shí)間。值得注意的是,如果打開微信之后,恰好有個(gè)常用聯(lián)系人的昵稱叫做“發(fā)現(xiàn)”,那就可能會(huì)被誤點(diǎn),這種情況下我們需要使用別的定位方式來(lái)定位特定控件。
需要點(diǎn)擊的文字如果是固定的,就可以使用d(text="XXX")來(lái)選擇控件元素,其中XXX為特定的文字。如果部分文字是固定的,比如第一次元素顯示文字為“我是第11932位訪客”,第二次顯示文字為“我是第12111位訪客”,那我們可以通過(guò)d(textContains="我是第").click()來(lái)點(diǎn)擊這個(gè)控件,或者通過(guò)d(textContains="位訪客").click()來(lái)點(diǎn)擊這個(gè)控件,這種方式就可以通過(guò)子字符串來(lái)定位特定的元素控件。
還是使用進(jìn)入朋友圈舉例:
import uiautomator2 as u2 import time d = u2.connect() # 連接設(shè)備 d.app_start("com.tencent.mm") # 打開微信 time.sleep(2) # 等待2秒鐘 # 點(diǎn)擊“發(fā)現(xiàn)”,三選一 d(text='發(fā)現(xiàn)').click() # 點(diǎn)擊文字為“發(fā)現(xiàn)”控件 d(textContains='發(fā)').click() # 點(diǎn)擊帶“發(fā)”的控件 # 通過(guò)WEditor獲得的xpath定位 d.xpath('//*[@resource-id="com.tencent.mm:id/e8y"]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[3]/android.widget.LinearLayout[1]').click() time.sleep(2) # 等待2秒鐘 # 點(diǎn)擊“朋友圈”,三選一 d(text='朋友圈').click() # 點(diǎn)擊文字為“朋友圈”控件 d(textContains='朋').click() # 點(diǎn)擊帶“朋”的控件 # 通過(guò)WEditor獲得的xpath定位 d.xpath('//*[@resource-id="android:id/list"]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]').click()
其實(shí)還有很多各不相同的定位方式,只要能定位到唯一的特定的控件進(jìn)行點(diǎn)擊即可。例如在雙十一時(shí),我在淘寶中切換到收集喵幣頁(yè)面的點(diǎn)擊事件:
import uiautomator2 as u2 import time d = u2.connect() # 連接設(shè)備 d.app_start("com.taobao.taobao") # 打開淘寶 time.sleep(5) # 等待5秒鐘 d.xpath('//*[@content-desc="雙11超級(jí)喵糖"]').click() # 打開喵糖頁(yè)面
6. 其它細(xì)節(jié)
在雙十一淘寶活動(dòng)中,打開喵糖頁(yè)面,會(huì)先彈出提示是否將此頁(yè)面加入收藏的彈框,點(diǎn)擊文字為“我再想想”的按鈕。注意要判斷此控件是否存在,點(diǎn)擊不存在的控件將會(huì)報(bào)錯(cuò)。如果不確定一個(gè)控件是否存在,又不想判斷的情況下,則需要使用 try......catch...... 來(lái)將其包裹。
if len(d(textContains='我再想想')) > 0: # 如果存在此控件 d(textContains='我再想想').click() # 點(diǎn)擊“我再想想”
點(diǎn)擊“賺糖”控件,因?yàn)檫@個(gè)控件經(jīng)常會(huì)被屏幕上出現(xiàn)的手指動(dòng)畫所擋住,因此需要等待:
while len(d(textContains='賺糖')) <= 0: time.sleep(1) d(textContains='賺糖').click()
然后點(diǎn)擊完后等會(huì)兒,再點(diǎn)擊“去瀏覽”按鈕:
while len(d(textContains='去瀏覽')) > 0: print("檢測(cè)到瀏覽按鈕...") d(textContains='去瀏覽').click()
等待15秒(算上反應(yīng)時(shí)間,需要多等一會(huì)兒)返回即可:
d.press("back") # 相當(dāng)于手機(jī)返回鍵
7. 總結(jié)
其實(shí)具體的部分實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,在此總結(jié)一下uiautomator2 的其它一些功能。
關(guān)于按鍵:
d.press("home")# 點(diǎn)擊home鍵 d.press("back")# 點(diǎn)擊back鍵 d.press("left")# 點(diǎn)擊左鍵 d.press("right") # 點(diǎn)擊右鍵 d.press("up") # 點(diǎn)擊上鍵 d.press("down")# 點(diǎn)擊下鍵 d.press("center") # 點(diǎn)擊選中 d.press("menu")# 點(diǎn)擊menu按鍵 d.press("search") # 點(diǎn)擊搜索按鍵 d.press("enter") # 點(diǎn)擊enter鍵 d.press("delete") # 點(diǎn)擊刪除按鍵 d.press("recent") # 點(diǎn)擊近期活動(dòng)按鍵 d.press("volume_up") # 音量+ d.press("volume_down") # 音量- d.press("volume_mute") # 靜音 d.press("camera") # 相機(jī) d.press("power") # 電源鍵
關(guān)于鎖屏與解鎖:
# 一個(gè)設(shè)備信息字典中的布爾值,為true時(shí)代表當(dāng)前屏幕亮起,為false代表當(dāng)前屏幕熄滅 d.info.get('screenOn') # 僅點(diǎn)亮屏幕 d.screen_on() # 點(diǎn)亮屏幕并解鎖,注意如果有密碼,則只能進(jìn)入密碼輸入頁(yè)面,需要輸入密碼才能解鎖 d.unlock() # 關(guān)閉屏幕 d.screen_off()
關(guān)于點(diǎn)擊等操作(支持百分比):
# 單擊屏幕 d.click(x,y) # x,y為點(diǎn)擊坐標(biāo) # 雙擊屏幕 d.double_click(x, y) d.double_click(x, y, 0.1) # 默認(rèn)兩個(gè)單擊之間間隔時(shí)間為0.1秒 # 長(zhǎng)按 d.long_click(x, y) d.long_click(x, y, 0.5) # 長(zhǎng)按0.5秒(默認(rèn)) # 滑動(dòng) d.swipe(sx, sy, ex, ey) d.swipe(sx, sy, ex, ey, 0.5) # 滑動(dòng)0.5秒(默認(rèn)) #拖動(dòng) d.drag(sx, sy, ex, ey) d.drag(sx, sy, ex, ey, 0.5) # 拖動(dòng)0.5秒(默認(rèn)) # 滑動(dòng)點(diǎn) 多用于九宮格解鎖,提前獲取到每個(gè)點(diǎn)的相對(duì)坐標(biāo)(這里支持百分比) # 從點(diǎn)(x0, y0)滑到點(diǎn)(x1, y1)再滑到點(diǎn)(x2, y2) # 兩點(diǎn)之間的滑動(dòng)速度是0.2秒 d.swipe((x0, y0), (x1, y1), (x2, y2), 0.2) # 注意:?jiǎn)螕簦瑒?dòng),拖動(dòng)操作支持百分比位置值。例: d.long_click(0.5, 0.5) 表示長(zhǎng)按屏幕中心
當(dāng)然還有其它的一些功能,例如向上滑動(dòng)屏幕,直到指定文字出現(xiàn)為止:
d(scrollable=True).scroll.to(text="3年級(jí)2班")
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注本站的更多內(nèi)容!
版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。