淺談如何使用Python控制手機(二)
1. 序言
每年淘寶雙十一的時候,總是要刷各種各樣的瀏覽頁面,收集能量或者喵幣或者什么。
那既然如此,我就總想著,能否通過Python自動調(diào)用的方式來刷網(wǎng)頁。
2. 前置工作
本文是基于使用Python控制手機(一),默認已經(jīng)安裝了ADB并配置了環(huán)境變量,安裝了Python環(huán)境,且在Python中安裝了uiautomator2和weditor等包。
3. 打開APP
當我們使用uiautomator2包來打開某個APP時,可以通過點擊屏幕特殊位置的方式來實現(xiàn)。但是其中存在的問題便是,可能由于我們APP圖標的移動,而使得程序無法運行。健壯性和通用性不高。
其實在uiautomator2這個包中,提供了一種可以通過APP包名就可以打開特定APP的方式,例如打開和關(guān)閉淘寶。
import uiautomator2 as u2 import time d = u2.connect() # 連接設備 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() # 連接設備 d.app_start("com.tencent.mm") # 打開微信 time.sleep(10) # 等待10秒鐘 d.app_stop("com.tencent.mm") # 關(guān)閉微信
4. 獲取APP的包名
有的時候,我們是不太清楚一個APP的包名的,這時我們可以通過打印設備當前信息的方式來獲取APP的包名。首先我們需要將要獲取的APP打開,并且保持在手機最前臺
執(zhí)行代碼:
import uiautomator2 as u2 import time d = u2.connect() # 連接設備 print(d.info) # 打印設備信息
輸出結(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鍵值對中,鍵currentPackageName對應的值,即為此時正在最前臺的APP的包名,上述結(jié)果操作時,正在最前的APP為淘寶。
5. 打開特定頁面
一般來說,如果頁面切換按鈕含有特定文字,我們直接通過文字進行定位是最方便的,也是最準確的,比如打開微信朋友圈:
import uiautomator2 as u2 import time d = u2.connect() # 連接設備 d.app_start("com.tencent.mm") # 打開微信 time.sleep(2) # 等待2秒鐘 d(text='發(fā)現(xiàn)').click() # 點擊文字為“發(fā)現(xiàn)”的控件 time.sleep(2) # 等待2秒鐘 d(text='朋友圈').click() # 點擊文字為“朋友圈”的控件
因為可能存在的,APP的加載時間和對點擊操作的響應時間,盡量在每次點擊操作之后,為APP和手機留有足夠的反應時間。值得注意的是,如果打開微信之后,恰好有個常用聯(lián)系人的昵稱叫做“發(fā)現(xiàn)”,那就可能會被誤點,這種情況下我們需要使用別的定位方式來定位特定控件。
需要點擊的文字如果是固定的,就可以使用d(text="XXX")來選擇控件元素,其中XXX為特定的文字。如果部分文字是固定的,比如第一次元素顯示文字為“我是第11932位訪客”,第二次顯示文字為“我是第12111位訪客”,那我們可以通過d(textContains="我是第").click()來點擊這個控件,或者通過d(textContains="位訪客").click()來點擊這個控件,這種方式就可以通過子字符串來定位特定的元素控件。
還是使用進入朋友圈舉例:
import uiautomator2 as u2 import time d = u2.connect() # 連接設備 d.app_start("com.tencent.mm") # 打開微信 time.sleep(2) # 等待2秒鐘 # 點擊“發(fā)現(xiàn)”,三選一 d(text='發(fā)現(xiàn)').click() # 點擊文字為“發(fā)現(xiàn)”控件 d(textContains='發(fā)').click() # 點擊帶“發(fā)”的控件 # 通過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秒鐘 # 點擊“朋友圈”,三選一 d(text='朋友圈').click() # 點擊文字為“朋友圈”控件 d(textContains='朋').click() # 點擊帶“朋”的控件 # 通過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()
其實還有很多各不相同的定位方式,只要能定位到唯一的特定的控件進行點擊即可。例如在雙十一時,我在淘寶中切換到收集喵幣頁面的點擊事件:
import uiautomator2 as u2 import time d = u2.connect() # 連接設備 d.app_start("com.taobao.taobao") # 打開淘寶 time.sleep(5) # 等待5秒鐘 d.xpath('//*[@content-desc="雙11超級喵糖"]').click() # 打開喵糖頁面
6. 其它細節(jié)
在雙十一淘寶活動中,打開喵糖頁面,會先彈出提示是否將此頁面加入收藏的彈框,點擊文字為“我再想想”的按鈕。注意要判斷此控件是否存在,點擊不存在的控件將會報錯。如果不確定一個控件是否存在,又不想判斷的情況下,則需要使用 try......catch...... 來將其包裹。
if len(d(textContains='我再想想')) > 0: # 如果存在此控件 d(textContains='我再想想').click() # 點擊“我再想想”
點擊“賺糖”控件,因為這個控件經(jīng)常會被屏幕上出現(xiàn)的手指動畫所擋住,因此需要等待:
while len(d(textContains='賺糖')) <= 0: time.sleep(1) d(textContains='賺糖').click()
然后點擊完后等會兒,再點擊“去瀏覽”按鈕:
while len(d(textContains='去瀏覽')) > 0: print("檢測到瀏覽按鈕...") d(textContains='去瀏覽').click()
等待15秒(算上反應時間,需要多等一會兒)返回即可:
d.press("back") # 相當于手機返回鍵
7. 總結(jié)
其實具體的部分實現(xiàn)起來比較簡單,在此總結(jié)一下uiautomator2 的其它一些功能。
關(guān)于按鍵:
d.press("home") # 點擊home鍵 d.press("back") # 點擊back鍵 d.press("left") # 點擊左鍵 d.press("right") # 點擊右鍵 d.press("up") # 點擊上鍵 d.press("down") # 點擊下鍵 d.press("center") # 點擊選中 d.press("menu") # 點擊menu按鍵 d.press("search") # 點擊搜索按鍵 d.press("enter") # 點擊enter鍵 d.press("delete") # 點擊刪除按鍵 d.press("recent") # 點擊近期活動按鍵 d.press("volume_up") # 音量+ d.press("volume_down") # 音量- d.press("volume_mute") # 靜音 d.press("camera") # 相機 d.press("power") # 電源鍵
關(guān)于鎖屏與解鎖:
# 一個設備信息字典中的布爾值,為true時代表當前屏幕亮起,為false代表當前屏幕熄滅 d.info.get('screenOn') # 僅點亮屏幕 d.screen_on() # 點亮屏幕并解鎖,注意如果有密碼,則只能進入密碼輸入頁面,需要輸入密碼才能解鎖 d.unlock() # 關(guān)閉屏幕 d.screen_off()
關(guān)于點擊等操作(支持百分比):
# 單擊屏幕 d.click(x,y) # x,y為點擊坐標 # 雙擊屏幕 d.double_click(x, y) d.double_click(x, y, 0.1) # 默認兩個單擊之間間隔時間為0.1秒 # 長按 d.long_click(x, y) d.long_click(x, y, 0.5) # 長按0.5秒(默認) # 滑動 d.swipe(sx, sy, ex, ey) d.swipe(sx, sy, ex, ey, 0.5) # 滑動0.5秒(默認) #拖動 d.drag(sx, sy, ex, ey) d.drag(sx, sy, ex, ey, 0.5) # 拖動0.5秒(默認) # 滑動點 多用于九宮格解鎖,提前獲取到每個點的相對坐標(這里支持百分比) # 從點(x0, y0)滑到點(x1, y1)再滑到點(x2, y2) # 兩點之間的滑動速度是0.2秒 d.swipe((x0, y0), (x1, y1), (x2, y2), 0.2) # 注意:單擊,滑動,拖動操作支持百分比位置值。例: d.long_click(0.5, 0.5) 表示長按屏幕中心
當然還有其它的一些功能,例如向上滑動屏幕,直到指定文字出現(xiàn)為止:
d(scrollable=True).scroll.to(text="3年級2班")
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
python-tornado的接口用swagger進行包裝的實例
今天小編就為大家分享一篇python-tornado的接口用swagger進行包裝的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08Python 實現(xiàn)取多維數(shù)組第n維的前幾位
今天小編就為大家分享一篇Python 實現(xiàn)取多維數(shù)組第n維的前幾位,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11python 刪除excel表格重復行,數(shù)據(jù)預處理操作
這篇文章主要介紹了python 刪除excel表格重復行,數(shù)據(jù)預處理操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07Python?通過colorama?設置控制臺、命令行輸出彩色文字
這篇文章主要介紹了Python?通過colorama?設置控制臺、命令行輸出彩色文字的相關(guān)資料,需要的朋友可以參考下2023-09-09如何不用安裝python就能在.NET里調(diào)用Python庫
這篇文章主要介紹了如何不用安裝python就能在.NET里調(diào)用Python庫,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-07-07Python基于TCP實現(xiàn)會聊天的小機器人功能示例
這篇文章主要介紹了Python基于TCP實現(xiàn)會聊天的小機器人功能,結(jié)合實例形式分析了Python通過socket模塊實現(xiàn)TCP連接的客戶端與服務器端模擬聊天機器人功能相關(guān)操作技巧,需要的朋友可以參考下2018-04-0412個Python程序員面試必備問題與答案(小結(jié))
這篇文章主要介紹了12個Python程序員面試必備問題與答案,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-06-06