99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀聊聊 PC 端自動化最佳方案 - WinAppDriver
聊聊 PC 端自動化最佳方案 - WinAppDriver
2021-08-10
收藏

來源:AirPython

作者:星安果

聊聊 PC 端自動化最佳方案 - WinAppDriver

1. 前言

大家好,我是安果!

一提到自動化,可能大家想到的是 App 端的 Appium、Airtest、AutoJS,亦或是 Selenium、Puppeteer、Cypress 等 Web 端的自動化框架

本篇文章,我將和大家聊聊 PC 端的自動化工具 - WinAppDriver

2. 準(zhǔn)備

WinAppDriver,全稱為 Windows Application Driver,它是 Windows 上一個類似 Selenium 的 UI 自動化驅(qū)動服務(wù)框架

它支持 Appium,可以使用 Appium-Python-Client 依賴庫完成對 Windows 桌面程序的自動化操作

項(xiàng)目地址:
https://github.com/Microsoft/WinAppDriver

需要注意的是,要使用 WinAppDriver 服務(wù)框架完成 Windows 的自動化,需要滿足 Windows10 或 Windows Server 2016 以上系統(tǒng)

另外,它支持的應(yīng)用程序包含:

  • UWP - Universal Windows Platform
  • WinForms - Windows Forms
  • WPF - Windows Presentation Foundation
  • Win32 - Classic Windows

在實(shí)現(xiàn)之前,我們需要做好以下準(zhǔn)備工作

2-1 開啟「 開發(fā)者模式 」

關(guān)鍵字搜索「 開發(fā)者設(shè)置 」,選擇開啟「 開發(fā)者模式 」

聊聊 PC 端自動化最佳方案 - WinAppDriver

2-2 安裝窗口組件元素識別工具

常用的 2 種窗口元素識別工具為:inspect.exe、FlaUInspect

其中

作為官方的組件元素識別工具,inspect.exe 集成于 Windows SDK

如果本地不存在該文件,可以通過下面鏈接進(jìn)行安裝

https://download.microsoft.com/download/4/d/2/4d2b7011-606a-467e-99b4-99550bf24ffc/windowssdk/winsdksetup.exe

相比 inspect.exe,F(xiàn)laUInspect 界面更簡潔,功能更易用( 推薦 )

項(xiàng)目地址:
https://github.com/FlaUI/FlaUInspect

2-3 安裝 WinAppDriver

通過下面鏈接下載 WinAppDriver 應(yīng)用程序,并在本地運(yùn)行起來

https://github.com/Microsoft/WinAppDriver/releases

2-4 搭建 Appium 環(huán)境

這部分內(nèi)容涉及 NodeJS 安裝及 Appium-Server 環(huán)境的搭建

可以參考:
https://www.cnblogs.com/amoyshmily/p/10500687.html

2-5 安裝依賴

最后安裝 Python 依賴庫 Appium-Python-Client

# 安裝依賴 Appium-Python-Client
pip3 install Appium-Python-Client

3. 實(shí)戰(zhàn)一下

我們以操作 PC 端的微信為例,聊聊自動化的常見步驟

首先,我們在本機(jī)打開 WinAppDriver 服務(wù),讓它在后臺運(yùn)行

然后,我們使用 Python 編寫自動化腳本

通過 ip 地址、端口號及 PC 版微信的絕對路徑,使用 Appium 打開微信

import time, os
from appium import webdriver
from selenium.webdriver import ActionChains
from
selenium.webdriver.common.keys import Keys

from time import sleep
class Auto():
def open_weixin(self, host='localhost', port=4723):
# 打開WinAppDriver服務(wù)
# 注意:如果手動開啟,則可以注釋掉
# os.system(r'start "" /d "C:Program FilesWindows Application Driver" "WinAppDriver.exe"')
# 配置信息
# 包含:平臺名、系統(tǒng)、應(yīng)用程序絕對路徑
desired_caps = {'platformName': 'Windows', 'deviceName': 'WindowsPC',
'app': r"D:Program Files (x86)TencentWeChatWeChat.exe"}
try:
# 連接WinAppDriver服務(wù),打開目標(biāo)軟件
self.driver = webdriver.Remote('http://{}:{}'.format(host, port), desired_caps)
except Exception as e:
raise AssertionError(e)

接著,通過「 組件元素識別工具 」拿到界面元素的屬性值,執(zhí)行常見的點(diǎn)擊、移動、滑動等操作

比如:點(diǎn)擊「 文件傳輸助手 」,發(fā)送一條信息

# 給文件傳輸助手發(fā)送一條信息
def send_msg(self, element_name, msg):
"""
:param element_name:元素name值
:param msg:
:return:
"""
# 通過name屬性,找到目標(biāo)元素
chat_element =
self.weixin_driver.find_element_by_name(target_name)

# 點(diǎn)擊元素,進(jìn)入聊天界面
chat_element.click()
# 找到輸入框,并輸入

self.weixin_driver.find_element_by_name("輸入").send_keys(msg)

# 點(diǎn)擊右下角的發(fā)送,發(fā)送消息出去

self.weixin_driver.find_element_by_name("發(fā)送(S)").click()

需要注意的是,如果涉及界面的滑動,可以使用「 ActionChains 」移動鼠標(biāo),然后使用 win32api 和 win32con 模擬屏幕滑動即可

import win32api
import win32con
from appium import webdriver
from selenium.webdriver import ActionChains
# 模擬屏幕滑動
# 1、移動到某個元素區(qū)域
ActionChains(self.weixin_driver).move_to_element(

self.weixin_driver.find_element_by_name("element_name")).perform()

# 2、滑動界面
# 比如,向上滾動,模擬滑動
win32api.mouse_event(
win32con.MOUSEEVENTF_WHEEL, 0, 0, -500)

完成自動化操作后,就可以主動釋放資源、關(guān)閉 WinAppDriver 服務(wù)

# 釋放資源及關(guān)閉服務(wù)
def tearDownFunc(self):
print("準(zhǔn)備退出")
sleep(2)
# 1、釋放資源
self.weixin_driver.quit()
# 2、關(guān)閉WinAppDriver應(yīng)用程序
os.system(' @taskkill /f /im WinAppDriver.exe')

4. 最后

在實(shí)際使用過程中,可能會遇到復(fù)雜的桌面應(yīng)用程序,這時我們可以通過打印驅(qū)動對象的「 page_source」元素控制樹值,以此來幫助我們進(jìn)行快速定位元素,進(jìn)而完善自動化腳本

數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗(yàn)證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }