安卓手机 Python 自动化( uiautomation、uiautomation2、weditor )
其他自動化工具或者框架:
- Airtest:https://airtest.readthedocs.io/zh_CN/latest/
- autojs:Auto.js快速入門實戰教程:https://zhuanlan.zhihu.com/p/90065914
- appium:https://blog.csdn.net/freeking101/article/details/107881979
AutomateIt、Automate、按鍵精靈、AutoJS 等 Android 自動化工具有什么特點?:https://www.zhihu.com/question/59503646
1、uiautomation
From:https://blog.csdn.net/ma524654165/article/details/77686526
? ? ? ? 主要用到一個 uiautomation 的開源框架,是一個國人用 Python 封裝 Windows GUI (UI Automation) 而成的自動化工具;
開源作者原文:http://www.cnblogs.com/Yinkaisheng/p/3444132.html
Github 地址:https://github.com/yinkaisheng/Python-UIAutomation-for-Windows
此自動化的主要思想:利用此框架抓取到程序的各種句柄,然后對句柄執行各種操作。
一、uiautomation 方法
- 1、WindowContrl(searchDepth,ClassName,SubName)
? ? ? ? 查找窗口中的程序,如果有中文則需用Unicode;可用window.Exists(maxSearchSeconds)來判斷此窗口是否存在; - 2、EditControl(searchFromControl)
? ? ? ? 查找編輯位置,找到后可用DoubleClick()來改變電腦的focus;edit.SetValue("string")輸入值; - 3、Win32API.SendKeys("string")?
? ? ? ? 如果已在編輯位置,則可用此方法來輸入值,{Ctrl}為ctrl鍵,其他類似;{@??8}格式可輸入8個@,
? ? ? ? 對于數字也可實現此功能,但對于字母不能...; - 4、MenuItemControl(searchFromControl,Name)???? ?????? ?????? 查找菜單按鈕;
- 5、ComboBoxControl(searchFromControl,AutomationI) ?????
? ? ? ? 查找下拉框,然后在此基礎上用Select("name")方法來選擇需要的選項; - 6、BottonControl(searchFromControl,Name,SubName) ?????? 查找按鈕;
- 7、automation.FindControl(firefoxWindow,lambda c:(isinstance(c, automation.EditControl) or isinstance(c, automation.ComboBoxControl)) and c.Name == 'Enter your search term')? ?按條件搜索handle
二、對找到句柄常用操作
- Click()??????????? 點擊;
- RighClik()?????? 右鍵點擊;
- SendKeys()???? 發送字符;
- SetValue()????? 傳值,一般對EditControl用;
三、對 windows 程序常用操作
- subprocess.Popen('Name')? 用進程打開程序;
- window.Close()???? 關閉窗口;
- window.SetActive()?????? 使用;
- window.SetTopMost()?? 設置為頂層
- window.ShowWindow(uiautomation.ShowWindow.Maximize)? 窗口最大化
- window.CaptureToImage('Notepad.png')? 截圖;
- uiautomation.Win32API.PressKey(uiautomation.Keys.VK_CONTROL)??? 按住Ctrl鍵
- uiautomation.Win32API.ReleaseKey(uiautomation.Keys.VK_CONTROL) 釋放Ctrl鍵
- automation.GetConsoleWindow()????? #return console window that runs python,打開控制臺
- automation.Logger.ColorfulWriteLine('\nI will open <Color=Green>Notepad</Color> and <Color=Yellow>automate</Color> it. Please wait for a while.')? 控制臺傳值(彩色字體),普通傳值用WriteLine;
- automation.ShowDesktop() 顯示桌面;
四、句柄的抓取
直接運行 automation 模塊枚舉窗口時,支持下列參數(從 doc 窗口運行 automation.py 程序 ):
-t intValue???? 延遲枚舉時間,單位秒 -r??????????????從樹的根部枚舉,如果不指定,從當前窗口枚舉 -d intValue??? 枚舉控件樹的的深度,如果不指定,枚舉整個樹 -f??????????????從焦點控件枚舉,如果不指定,從當前窗口枚舉 -c??????????????從光標下的控件枚舉,如果不指定,從當前窗口枚舉 -a??????????????獲取光標下控件及其所有父控件 -n??????????????顯示控件的完整Name, 如果不指定,只顯示前30個字符 -m??????????????顯示控件更多屬性,默認只顯示控件的四個屬性示例:
automation.pyc –t3, 3秒后枚舉當前窗口所有控件 automation.pyc –d2 –t3, 3秒后枚舉當前窗口前三層控件 automation.pyc –r –d1 –t0 -n, 0秒后從根部枚舉前兩層控件,并顯示控件完整名稱 automation.pyc –c –t3, 3秒后顯示鼠標光標下面的控件信息2、UIAutomator2
參考
- :https://vic.kim/2019/05/20/UIAutomator2的使用/
- :https://blog.csdn.net/d1240673769/article/details/113809889
uiautomator2 是一個可以使用 Python 對 Android 設備進行UI自動化的庫。其底層基于 Google uiautomator,Google 提供的 uiautomator 庫可以獲取屏幕上任意一個 APP 的任意一個控件屬性,并對其進行任意操作。
uiautomator2 不是 android SDK 下的 uiautomator,而是一個 python 庫,用于 Android 的 ui 自動化測試。使用 uiautomator2 只能用于?android 端測試,不像 appium 可以跨平臺可用于 ios 端。使用 uiautomator2 可以使用 wifi 或數據線和手機相連。
GitHub地址:https://github.com/openatx/uiautomator2
? ? ? ? ? ? https://github.com/openatx/uiautomator2/blob/master/README.md
工作原理:
如圖所示,python-uiautomator2 主要分為兩個部分,python 客戶端,移動設備
- Python端:運行腳本,并向移動設備發送 HTTP 請求
- 移動設備:移動設備上運行了封裝了 uiautomator2 的 HTTP 服務,解析收到的請求,并轉化成 uiautomator2 的代碼。
整個過程
安裝 uiautomator2
pip install --pre uiautomator2?
pip install pillow (如果需要截圖,可安裝這個庫)
設備安裝 atx-agent
首先設備連接到 PC,并能夠 adb devices 發現該設備。
執行下面的命令
然后就會自動安裝庫所需要的設備端程序:uiautomator-server,atx-agent,openstf / minicap,openstf / minitouch。 最后提示 success,代表 atx-agent 初始化成功。
安裝 weditor
有了這個,方便我們快速的識別手機上的元素,方便寫代碼
pip install -U weditor安裝好之后,就可以在命令行運行?weditor --help?確認是否安裝成功了。Windows 系統可以使用命令在桌面創建一個快捷方式:weditor --shortcut??,在 windows cmd 中執行上述命令后,會在桌面上創建一個快捷方式,如下圖:
安裝 weditor 報錯 UnicodeDecodeError 時,可以安裝老版本:pip install weditor==0.6.3
啟動方法
- 方法 1:命令行執行?weditor?會自動打開瀏覽器,輸入 設備的IP?或者 序列號( 序列號可以通過 adb devices 命令查看得到?),然后點擊 Connect
- 方法 2:桌面上雙擊 WEditor 快捷方式即可。
- 方法 3:命令行中執行?python -m weditor
啟動后如下圖:
應用以及操作
調用 uiautomator2 的過程
配置手機設備參數,設置具體操作的是哪一臺手機
抓取手機上應用的控件,制定對應的控件來進行操作
對抓取到的控件進行操作,比如點擊、填寫參數等。
設備連接方法,有兩種:
python-uiautomator2 連接手機的方式有兩種,
- 一種是通過WIFI。WIFI 最便利的地方是可以不用連接數據線
- 一種是通過USB。USB則可以用在PC和手機網絡不在一個網段用不了的情況。
(1)通過WiFi,假設設備IP 192.168.0.107和您的PC在同一網絡中
import uiautomator2 as u2 d = u2.connect('192.168.0.107')(2)通過USB, 假設設備序列是123456789F
import uiautomator2 as u2 d = u2.connect('123456789F') # USB鏈接設備。或者u2.connect_usb('123456f') #d = u2.connect_usb() 或者 d = u2.connect() ,當前只有一個設備時可以用這個在沒有參數的情況下調用 u2.connect(), uiautomator2 將從環境變量 ANDROID_DEVICE_IP 獲取設備 IP。如果這個環境變量是空的,uiautomator 將返回 connect_usb,您需要確保只有一個設備連接到計算機。
檢查并維持設備端守護進程處于運行狀態:
d.healthcheck()打開調試開關:
d.debug = True d.info安裝應用,只能從URL安裝:
d.app_install('http://some-domain.com/some.apk') #引號內為下載apk地址啟動應用:
d.app_start('com.eg.android.AlipayGphone') #引號內為包名稱,這里為支付寶停止應用:
#相當于'am force-stop'強制停止應用 d.app_stop('com.eg.android.AlipayGphone') #相當于'pm clear' 清空App數據 d.app_clear('com.eg.android.AlipayGphone')停止所有正在運行的應用程序:
# 停止所有 d.app_stop_all()# 停止所有應用程序,除了com.examples.demo d.app_stop_all(excludes=['com.examples.demo'])跳過彈窗,禁止彈窗:
d.disable_popups() # 自動跳過彈出窗口 d.disable_popups(False) # 禁用自動跳過彈出窗獲取設備信息:
# 獲取基本信息 d.info# 獲取窗口大小 print(d.window_size()) # 設備垂直輸出示例: (1080, 1920) # 設備水平輸出示例: (1920, 1080)# 獲取當前應用程序信息。對于某些android設備,輸出可以為空 print(d.current_app())#獲取設備序列號 print(d.serial)#獲取WIFI IP print(d.wlan_ip)#獲取詳細的設備信息 print(d.device_info)獲取應用信息:
d.app_info("com.eg.android.AlipayGphone") # 會輸出 ''' {"packageName": "com.eg.android.AlipayGphone", "mainActivity": "com.eg.android.AlipayGphone.AlipayLogin", "label": "支付寶", "versionName": "10.2.13.9020", "versionCode": 360, "size": 108306104 } ''' # 保存應用程序圖標 img = d.app_icon("com.eg.android.AlipayGphone") img.save("icon.png")推拉文件:
(1)將文件推送到設備
# push文件夾 d.push("foo.txt", "/sdcard/") # push和重命名 d.push("foo.txt", "/sdcard/bar.txt") # push fileobj with open("foo.txt", 'rb') as f:d.push(f, "/sdcard/") # 推動和更改文件訪問模式 d.push("foo.sh", "/data/local/tmp/", mode=0o755)(2)從設備中拉出一個文件
d.pull("/sdcard/tmp.txt", "tmp.txt")# 如果在設備上找不到文件,FileNotFoundError將引發 d.pull("/sdcard/some-file-not-exists.txt", "tmp.txt")關鍵事件 ( 屏幕、鍵盤?操作?):
(1)打開/關閉屏幕
d.screen_on()#打開屏幕 d.screen_off() #關閉屏幕(2)獲取當前屏幕狀態
d.info.get('screenOn') # 需要 Android> = 4.4(3)硬鍵盤和軟鍵盤操作
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") #電源鍵(4)解鎖屏幕
d.unlock() # 相當于 # 1. 發射活動:com.github.uiautomator.ACTION_IDENTIFY # 2. 按home鍵手勢與設備的交互:
# 單擊屏幕 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.5s(default)#拖動 d.drag(sx, sy, ex, ey) d.drag(sx, sy, ex, ey, 0.5)#拖動0.5s(default) # 滑動點 多用于九宮格解鎖,提前獲取到每個點的相對坐標(這里支持百分比)# 從點(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) 表示長按屏幕中心XPath:
# 檢索方向 d.orientation # 檢索方向。輸出可以是 "natural" or "left" or "right" or "upsidedown"# 設置方向 d.set_orientation("l") # or "left" d.set_orientation("r") # or "right" d.set_orientation("n") # or "natural"#凍結/ 開啟旋轉 d.freeze_rotation() # 凍結旋轉 d.freeze_rotation(False) # 開啟旋轉########## 截圖 ############ # 截圖并保存到電腦上的一個文件中,需要Android>=4.2。 d.screenshot("home.jpg")# 得到PIL.Image格式的圖像. 但你必須先安裝pillow image = d.screenshot() # default format="pillow" image.save("home.jpg") # 或'home.png',目前只支持png 和 jpg格式的圖像# 得到OpenCV的格式圖像。當然,你需要numpy和cv2安裝第一個 import cv2 image = d.screenshot(format='opencv') cv2.imwrite('home.jpg', image)# 獲取原始JPEG數據 imagebin = d.screenshot(format='raw') open("some.jpg", "wb").write(imagebin)############################## 轉儲UI層次結構 # get the UI hierarchy dump content (unicoded).(獲取UI層次結構轉儲內容) d.dump_hierarchy()# 打開通知或快速設置 d.open_notification() #下拉打開通知欄 d.open_quick_settings() #下拉打開快速設置欄# 檢查特定的UI對象是否存在 d(text="Settings").exists # 返回布爾值,如果存在則為True,否則為False d.exists(text="Settings") # 另一種寫法 # 高級用法 d(text="Settings").exists(timeout=3) # 等待'Settings'在3秒鐘出現# 獲取特定UI對象的信息 d(text="Settings").info# 獲取/設置/清除可編輯字段的文本(例如EditText小部件) d(text="Settings").get_text() #得到文本小部件 d(text="Settings").set_text("My text...") #設置文本 d(text="Settings").clear_text() #清除文本# 獲取Widget中心點 d(text="Settings").center() #d(text="Settings").center(offset=(0, 0)) # 基準位置左前UI 對象 的 五種 定位方式:
# text、resourceId、description、className、xpath、坐標# 執行單擊UI對象 #text定位單擊 d(text="Settings").click() d(text="Settings", className="android.widget.TextView").click()#resourceId定位單擊 d(resourceId="com.ruguoapp.jike:id/tv_title", className="android.widget.TextView").click() #description定位單擊 d(description="設置").click() d(description="設置", className="android.widget.TextView").click()#className定位單擊 d(className="android.widget.TextView").click()#xpath定位單擊 d.xpath("//android.widget.FrameLayout[@index='0']/android.widget.LinearLayout[@index='0']").click()#坐標單擊 d.click(182, 1264)# 等待元素出現(最多10秒),出現后單擊 d(text="Settings").click(timeout=10) # 在10秒時點擊,默認的超時0 d(text='Skip').click_exists(timeout=10.0) # 單擊直到元素消失,返回布爾 d(text="Skip").click_gone(maxretry=10, interval=1.0) # maxretry默認值10,interval默認值1.0 # 點擊基準位置偏移 d(text="Settings").click(offset=(0.5, 0.5)) # 點擊中心位置,同d(text="Settings").click() d(text="Settings").click(offset=(0, 0)) # 點擊左前位置 d(text="Settings").click(offset=(1, 1)) # 點擊右下# 執行雙擊UI對象 d(text="設置").double_click() # 雙擊特定ui對象的中心 d.double_click(x, y, 0.1) # 兩次單擊之間的默認持續時間為0.1秒#執行長按UI對象 # 長按特定UI對象的中心 d(text="Settings").long_click() d.long_click(x, y, 0.5) # 長按坐標位置0.5s默認# 將UI對象拖向另一個點或另一個UI對象 # Android<4.3不能使用drag. # 在0.5秒內將UI對象拖到屏幕點(x, y) d(text="Settings").drag_to(x, y, duration=0.5)# 將UI對象拖到另一個UI對象的中心位置,時間為0.25秒 d(text="Settings").drag_to(text="Clock", duration=0.25)常見用法:
# 等待10s d.xpath("//android.widget.TextView").wait(10.0)# 找到并單擊 d.xpath("//*[@content-desc='分享']").click()# 檢查是否存在 if d.xpath("//android.widget.TextView[contains(@text, 'Se')]").exists:print("exists")# 獲取所有文本視圖文本、屬性和中心點 for elem in d.xpath("//android.widget.TextView").all():print("Text:", elem.text)#獲取視圖文本 for elem in d.xpath("//android.widget.TextView").all():print("Attrib:", elem.attrib)#獲取屬性和中心點 #返回: (100, 200) for elem in d.xpath("//android.widget.TextView").all():print("Position:", elem.center())# xpath常見用法: # 所有元素 //*# resource-id包含login字符 //*[contains(@resource-id, 'login')]# 按鈕包含賬號或帳號 //android.widget.Button[contains(@text, '賬號') or contains(@text, '帳號')]# 所有ImageView中的第二個 (//android.widget.ImageView)[2]# 所有ImageView中的最后一個 (//android.widget.ImageView)[last()]# className包含ImageView //*[contains(name(), "ImageView")]會在瀏覽器中打開網頁,輸入設備 devices 信息 可以 通過 adb devices 來進行查詢設備 信息。出現樹的模樣,代表鏈接上手機,然后點擊右上角的 Reload 實時顯示手機頁面。 這樣就可以開始你的元素定位了。
通用的元素定位方式。
- (1) 根據文本進行定位:d(text=顯示的文本).click()
- (2) 通過 resourceId 進行定位:d(resourceId="com.tcl.tclplus:id/cart_layout").click()
- (3) 滑動 上 或者 下 。手指向上,就是頁面往下拉,分兩種情況 拉到底 或者 只拉一部分。
- 拉到底:d(scrollable=True).scroll.toEnd()
- 拉一部分:d.swipe(0.806, 0.801,0.818, 0.487) # 向上滑動 ?橫坐標可以不變,縱坐標是變化的,是變小的趨勢 ?這是手指向上
- 拉倒頁面首頁 開頭部分:d(scrollable=True).scroll.toBeginning(steps=50)
- (4) 滑動 左右?
????????d(scrollable=True).scroll.horiz.toEnd() #橫向滾動到最右側
????????d(scrollable=True).scroll.horiz.toBeginning() #橫向滾動到最左側
????或者
????????c.水平向右滾動:d(scrollable=True).scroll.horiz.forward(steps=50)
????????d.水平向左滾動:d(scrollable=True).scroll.horiz.backward(steps=50) - (5) 滑動到指定位置:滑動到文本為測試的位置:d(scrollable=True).scroll.to(text ='測試')
- (6) 元素判斷 ?可以這樣寫,通過判斷元素的存在性來執行不同的操作 s = self.d(resourceId="com.tcl.tclplus:id/iot_txt_home_name", text=u"立即登錄", className="android.widget.TextView" ) if len(s) == 0:print('元素未找到,執行退出操作')
- (7) 隨機字符串或者隨機字母 輸入 a = random.sample(string.ascii_letters, 4) data = ''.join([str(x) for x in a]) # 隨機從大小寫字母中取四位,然后寫入到輸入框中。 d(resourceId="com.tcl.tclplus:id/et_invoice_header").set_text(data)
- (8) 截圖 filepaths 就是截圖所存的路徑,可以自己填寫。filepaths = os.path.normpath(os.path.join(os.path.join(os.path.dirname(os.path.dirname(__file__)), "Automation/Tcase"))) def get_png(self, filename, filepath='/Member'):"""截圖操作,默認截圖的存儲路徑為Member"""imgName = filename + datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '.png' # 截圖可以單獨保存為別的名字的文件stringPath = filepaths + '/image' + filepath + '\\' + imgNameprint stringPath# img.save('filename.png')#圖片保存在當前項目的文件夾下邊self.d.screenshot().save(stringPath) # 保存文件到指定的文件夾下邊self.get_png(filename='訂單-取消購買'.decode('utf-8'), filepath='/Market/訂單') 實際調用的時候 需要進行decode
- (9) apk 自動安裝 def install_app(path):app_Path = lambda x: os.path.join(file_path, "app", x)apk = app_Path(path + ".apk")os.system('adb install -r -d ' + apk)time.sleep(5)
- (10) 報告生成 # 用例文件很多 采用 關鍵字匹配的方式進行。def UI_Report(testcase, ReportPath):"""根據傳入的testcase 來判斷執行哪種報告生成方式。"""def Report(s):@wraps(s)def creat_report():AA = hasattr(testcase,'__call__')# AA = isfunction(testcase)if AA:print '這個是函數'suite = unittest.makeSuite(testcase)fp = file(ReportPath, 'wb')runner = HTMLTestRunner(stream=fp, title=r'UI自動化', description=r'接口自動化測試報告')runner.run(suite) #區別fp.close()else:print '不是函數,是執行run_main方法'fp = file(ReportPath, 'wb')runner = HTMLTestRunner(stream=fp, title=r'UI自動化測試報告', description=r'商城')runner.run(testcase)fp.close()return creat_reportreturn Reportdef all_case():testcase = unittest.TestSuite() # 加載測試套件# 用例的目錄,關鍵字進行匹配discover = unittest.defaultTestLoader.discover(filepath, pattern='Market*.py', top_level_dir=None)testcase.addTest(discover)return testcase@UI_Report(testcase=all_case(),ReportPath=filepath+'/report/result.html')
def run():print '生成測試報告'if __name__ == '__main__':run()
因為 run_main 執行的時候,是打印所有用例文件+名稱,而通過測試套件 添加 類名稱時,執行方式不一樣。至于公共函數,比如啟動 app、一些共有的操作,可以寫到 公共函數中
?在unitest中 增加setupclass 函數 是只 啟動一次app,跟setup 區別一下,下面增加你的公共函數。然后用例文件中 直接通過繼承的方式來進行。
例如:class test(commons):
def del_file(filepath):listdir = os.listdir(filepath) # 獲取文件和子文件夾for rename in listdir:rename = filepath + "//" + renameif os.path.isfile(rename): # 是文件os.remove(rename) # 刪除文件elif os.path.isdir(rename): # 是子文件duellist = os.listdir(rename)for f in duellist: # 遍歷該子文件夾file_path = os.path.join(rename, f)if os.path.isfile(file_path): # 刪除子文件夾下文件os.remove(file_path)elif os.path.isdir(file_path): # 強制刪除子文件夾下的子文件夾shutil.rmtree(file_path)可以在用例文件執行開頭增加一些 調用方法
如刪除截圖 和初始化 app環境 都是可以的??
3、pyautogui?
From:https://www.jb51.net/article/183926.htm
在使用 Python 做 安卓自動化腳本 時,兩個庫可以使用,一個為 PyUserInput 庫,另一個為pyautogui 庫。就本人而言,我更喜歡使用pyautogui庫,該庫功能多,使用便利。下面給大家介紹一下pyautogui庫的使用方法。在cmd命令框中輸入pip3 install pyautogui即可安裝該庫!
常用操作
我們在 pyautogui 庫中常常使用的方法,如下:
import pyautogui# 調用在執行動作后暫停的秒數,只能在執行一些pyautogui動作后才能使用,建議用time.sleep pyautogui.PAUSE = 1# 啟用自動防故障功能,左上角的坐標為(0,0),將鼠標移到屏幕的左上角,來拋出failSafeException異常 pyautogui.FAILSAFE = True# 判斷(x,y)是否在屏幕上 x, y = 122, 244 pyautogui.onScreen(x, y) # 結果為truewidth, height = pyautogui.size() # 屏幕的寬度和高度 print(width, height)鼠標操作
我們在 pyautogui 庫對于鼠標的使用方法大體如下:
import pyautoguicurrentMouseX, currentMouseY = pyautogui.position() # 鼠標當前位置 print(currentMouseX, currentMouseY)# 控制鼠標移動,duration為持續時間 for i in range(2):pyautogui.moveTo(100, 100, duration=0.25) # 移動到 (100,100)pyautogui.moveTo(200, 100, duration=0.25)pyautogui.moveTo(200, 200, duration=0.25)pyautogui.moveTo(100, 200, duration=0.25)for i in range(2):pyautogui.moveRel(50, 0, duration=0.25) # 從當前位置右移100像素pyautogui.moveRel(0, 50, duration=0.25) # 向下pyautogui.moveRel(-50, 0, duration=0.25) # 向左pyautogui.moveRel(0, -50, duration=0.25) # 向上# 按住鼠標左鍵,把鼠標拖拽到(100, 200)位置 pyautogui.dragTo(100, 200, button='left') # 按住鼠標左鍵,用2秒鐘把鼠標拖拽到(300, 400)位置 pyautogui.dragTo(300, 400, 2, button='left') # 按住鼠標左鍵,用0.2秒鐘把鼠標向上拖拽 pyautogui.dragRel(0, -60, duration=0.2)# pyautogui.click( # x=moveToX, y=moveToY, clicks=num_of_clicks, # interval=secs_between_clicks, button='left' # ) # 其中,button屬性可以設置成left,middle和right。 pyautogui.click(10, 20, 2, 0.25, button='left') pyautogui.click(x=100, y=200, duration=2) # 先移動到(100, 200)再單擊 pyautogui.click() # 鼠標當前位置點擊一下 pyautogui.doubleClick() # 鼠標當前位置左擊兩下 pyautogui.doubleClick(x=100, y=150, button="left") # 鼠標在(100,150)位置左擊兩下 pyautogui.tripleClick() # 鼠標當前位置左擊三下pyautogui.mouseDown() # 鼠標左鍵按下再松開 pyautogui.mouseUp() pyautogui.mouseDown(button='right') # 按下鼠標右鍵 pyautogui.mouseUp(button='right', x=100, y=200) # 移動到(100, 200)位置,然后松開鼠標右鍵# scroll函數控制鼠標滾輪的滾動,amount_to_scroll參數表示滾動的格數。正數則頁面向上滾動,負數則向下滾動 # pyautogui.scroll(clicks=amount_to_scroll, x=moveToX, y=moveToY) pyautogui.scroll(5, 20, 2) pyautogui.scroll(10) # 向上滾動10格 pyautogui.scroll(-10) # 向下滾動10格 pyautogui.scroll(10, x=100, y=100) # 移動到(100, 100)位置再向上滾動10格# 緩動/漸變函數可以改變光標移動過程的速度和方向。通常鼠標是勻速直線運動,這就是線性緩動/漸變函數。 # PyAutoGUI有30種緩動/漸變函數,可以通過pyautogui.ease*?查看。 # 開始很慢,不斷加速 pyautogui.moveTo(100, 100, 2, pyautogui.easeInQuad) # 開始很快,不斷減速 pyautogui.moveTo(100, 100, 2, pyautogui.easeOutQuad) # 開始和結束都快,中間比較慢 pyautogui.moveTo(100, 100, 2, pyautogui.easeInOutQuad) # 一步一徘徊前進 pyautogui.moveTo(100, 100, 2, pyautogui.easeInBounce) # 徘徊幅度更大,甚至超過起點和終點 pyautogui.moveTo(100, 100, 2, pyautogui.easeInElastic)對于我們要獲取鼠標在屏幕中的位置,我們可以采用如下代碼:
# 案例獲取鼠標的位置,方便復制我們定位的鼠標坐標點到代碼中 import pyautogui import time# 獲取鼠標位置 def get_mouse_position():time.sleep(5) # 準備時間print('開始獲取鼠標位置')try:for i in range(10):# Get and print the mouse coordinates.x, y = pyautogui.position()positionStr = '鼠標坐標點(X,Y)為:{},{}'.format(str(x).rjust(4), str(y).rjust(4))pix = pyautogui.screenshot().getpixel((x, y)) # 獲取鼠標所在屏幕點的RGB顏色positionStr += ' RGB:(' + str(pix[0]).rjust(3) + ',' + str(pix[1]).rjust(3) + ',' + str(pix[2]).rjust(3) + ')'print(positionStr)time.sleep(0.5) # 停頓時間except:print('獲取鼠標位置失敗')if __name__ == "__main__":get_mouse_position()也可以使用pyautogui庫幫助文檔的方法,不過本人認為使用上面的方法,更加便利。pyautogui庫幫助文檔的獲取鼠標位置的方法如下:
import pyautoguiprint('Press Ctrl-C to quit.') try:while True:# Get and print the mouse coordinates.x, y = pyautogui.position()positionStr = 'X:' + str(x).rjust(4) + ' Y:' + str(y).rjust(4)pix = pyautogui.screenshot().getpixel((x, y)) # 獲取鼠標所在屏幕點的RGB顏色positionStr += ' RGB:(' + str(pix[0]).rjust(3) + ',' + \str(pix[1]).rjust(3) + ',' + str(pix[2]).rjust(3) + ')'print(positionStr, end='') # end='' 替換了默認的換行# 連續退格鍵并刷新,刪除之前打印的坐標,就像直接更新坐標效果print('\b' * len(positionStr), end='', flush=True) except KeyboardInterrupt: # 處理 Ctrl-C 按鍵print('\nDone.')鍵盤操作
我們在pyautogui庫對于鍵盤的使用方法大體如下:
import pyautoguipyautogui.typewrite('Hello world!') # 輸入Hello world!字符串 pyautogui.typewrite('Hello world!', interval=0.25) # 每次輸入間隔0.25秒,輸入Hello world!pyautogui.press('enter') # 按下并松開(輕敲)回車鍵 pyautogui.press(['left', 'left', 'left', 'left']) # 按下并松開(輕敲)四下左方向鍵 pyautogui.keyDown('shift') # 按下`shift`鍵 pyautogui.keyUp('shift') # 松開`shift`鍵pyautogui.keyDown('shift') pyautogui.press('4') pyautogui.keyUp('shift') # 輸出 $ 符號的按鍵pyautogui.hotkey('ctrl', 'v') # 組合按鍵(Ctrl+V),粘貼功能,按下并松開'ctrl'和'v'按鍵# pyautogui.KEYBOARD_KEYS數組中就是press(),keyDown(),keyUp()和hotkey()函數可以輸入的按鍵名稱 pyautogui.KEYBOARD_KEYS = ['\t', '\n', '\r', ' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.','/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@','[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l','m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~','accept', 'add', 'alt', 'altleft', 'altright', 'apps', 'backspace', 'browserback','browserfavorites', 'browserforward', 'browserhome', 'browserrefresh', 'browsersearch','browserstop', 'capslock', 'clear', 'convert', 'ctrl', 'ctrlleft', 'ctrlright', 'decimal','del', 'delete', 'divide', 'down', 'end', 'enter', 'esc', 'escape', 'execute', 'f1', 'f10','f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f2', 'f20', 'f21', 'f22','f23', 'f24', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'final', 'fn', 'hanguel', 'hangul','hanja', 'help', 'home', 'insert', 'junja', 'kana', 'kanji', 'launchapp1', 'launchapp2','launchmail', 'launchmediaselect', 'left', 'modechange', 'multiply', 'nexttrack','nonconvert', 'num0', 'num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7', 'num8', 'num9','numlock', 'pagedown', 'pageup', 'pause', 'pgdn', 'pgup', 'playpause', 'prevtrack', 'print','printscreen', 'prntscrn', 'prtsc', 'prtscr', 'return', 'right', 'scrolllock', 'select','separator', 'shift', 'shiftleft', 'shiftright', 'sleep', 'space', 'stop', 'subtract', 'tab','up', 'volumedown', 'volumemute', 'volumeup', 'win', 'winleft', 'winright', 'yen', 'command','option', 'optionleft', 'optionright' ]彈窗操作
我們在 pyautogui 庫對于彈出窗口的使用方法大體如下:
import pyautogui# 顯示一個簡單的帶文字和OK按鈕的消息彈窗。用戶點擊后返回button的文字。 pyautogui.alert(text='', title='', button='OK') b = pyautogui.alert(text='要開始程序么?', title='請求框', button='OK') print(b) # 輸出結果為OK# 顯示一個簡單的帶文字、OK和Cancel按鈕的消息彈窗,用戶點擊后返回被點擊button的文字,支持自定義數字、文字的列表。 pyautogui.confirm(text='', title='', buttons=['OK', 'Cancel']) # OK和Cancel按鈕的消息彈窗 pyautogui.confirm(text='', title='', buttons=range(10)) # 10個按鍵0-9的消息彈窗 a = pyautogui.confirm(text='', title='', buttons=range(10)) print(a) # 輸出結果為你選的數字# 可以輸入的消息彈窗,帶OK和Cancel按鈕。用戶點擊OK按鈕返回輸入的文字,點擊Cancel按鈕返回None。 pyautogui.prompt(text='', title='', default='')# 樣式同prompt(),用于輸入密碼,消息用*表示。帶OK和Cancel按鈕。 # 用戶點擊OK按鈕返回輸入的文字,點擊Cancel按鈕返回None。 pyautogui.password(text='', title='', default='', mask='*')圖像操作
我們在pyautogui庫對于圖像的使用方法大體如下:
import pyautogui# 截全屏并設置保存圖片的位置和名稱 pyautogui.screenshot(r'C:\Users\ZDH\Desktop\PY\my_screenshot.png') # 截全屏并設置保存圖片的位置和名稱 im = pyautogui.screenshot(r'C:\Users\ZDH\Desktop\PY\my_screenshot.png') print(im) # 打印圖片的屬性# 不截全屏,截取區域圖片。截取區域region參數為:左上角XY坐標值、寬度和高度 pyautogui.screenshot(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png', region=(0, 0, 300, 400) )pix = pyautogui.screenshot().getpixel((220, 200)) # 獲取坐標(220,200)所在屏幕點的RGB顏色 positionStr = ' RGB:(' + str(pix[0]).rjust(3) + ',' + \str(pix[1]).rjust(3) + ',' + str(pix[2]).rjust(3) + ')' print(positionStr) # 打印結果為RGB:( 60, 63, 65) pix = pyautogui.pixel(220, 200) # 獲取坐標(220,200)所在屏幕點的RGB顏色與上面三行代碼作用一樣 positionStr = ' RGB:(' + str(pix[0]).rjust(3) + ',' + \str(pix[1]).rjust(3) + ',' + str(pix[2]).rjust(3) + ')' print(positionStr) # 打印結果為RGB:( 60, 63, 65)# 如果你只是要檢驗一下指定位置的像素值,可以用pixelMatchesColor(x,y,RGB)函數,把X、Y和RGB元組值穿入即可 # 如果所在屏幕中(x,y)點的實際RGB三色與函數中的RGB一樣就會返回True,否則返回False # tolerance參數可以指定紅、綠、藍3種顏色誤差范圍 pyautogui.pixelMatchesColor(100, 200, (255, 255, 255)) pyautogui.pixelMatchesColor(100, 200, (255, 255, 245), tolerance=10)# 獲得文件圖片在現在的屏幕上面的坐標,返回的是一個元組(top, left, width, height) # 如果截圖沒找到,pyautogui.locateOnScreen()函數返回None a = pyautogui.locateOnScreen(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png') print(a) # 打印結果為Box(left=0, top=0, width=300, height=400) x, y = pyautogui.center(a) # 獲得文件圖片在現在的屏幕上面的中心坐標 print(x, y) # 打印結果為150 200# 這步與上面的四行代碼作用一樣 x, y = pyautogui.locateCenterOnScreen(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png') print(x, y) # 打印結果為150 200# 匹配屏幕所有與目標圖片的對象,可以用for循環和list()輸出 pyautogui.locateAllOnScreen(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png') for pos in pyautogui.locateAllOnScreen(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png'):print(pos) # 打印結果為Box(left=0, top=0, width=300, height=400) a = list(pyautogui.locateAllOnScreen(r'C:\Users\ZDH\Desktop\PY\region_screenshot.png')) print(a) # 打印結果為[Box(left=0, top=0, width=300, height=400)]參考資料
PyAutoGUI幫助文檔:
https://blog.csdn.net/qq_34053552/article/details/79776671
pyautogui圖形自動化,擊敗重復性辦公任務:
https://blog.csdn.net/qq_43017750/article/details/90575240
總結
以上是生活随笔為你收集整理的安卓手机 Python 自动化( uiautomation、uiautomation2、weditor )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络云存储技术Windows serve
- 下一篇: excel画图如何添加图表数据参考线