1.簡介
在實際工作中,我們進行web自動化的時候,檔案上傳是很常見的操作,例如上傳使用者頭像,上傳身份證資訊等。所以巨集哥打算按上傳檔案的分類對其進行一下講解和分享。
2.為什麼selenium沒有提供API?
想必小夥伴們或者童鞋們一定很好奇,既然上傳檔案在自動化這麼常見而且經常用到,那麼為什麼Selenium的webdriver為什麼不提供方法(API),巨集哥這裡解釋一下原因:因為上傳檔案需要開啟window視窗,webdriver是無法對window的控制元件操作的,換句話說就是:selenium無法識別非web的控制元件,上傳檔案視窗為系統自帶,無法識別視窗元素。所以沒有提供方法,需要我們換個思路去上傳檔案。
3.上傳檔案分類
首先,我們要區分出上傳按鈕的種類,大體上可以分為兩種,一種是input框,另外一種就比較複雜,通過js、flash等實現,標籤非input。
上傳檔案有兩種場景:input控制上傳和非input控制元件上傳。大多數情況都是input控制元件上傳檔案,只有非常少數的使用自定義的非input上傳檔案。今天巨集哥這一篇文章就用來介紹非input控制元件上傳檔案。
4.非input控制元件上傳檔案
非input控制元件上傳檔案,我們要引入外部外掛上傳。這種上傳千奇百怪,有用a標籤的,有用div的,有用button的,有用object的,我們沒有辦法通過直接在網頁上處理掉這些上傳,唯一的辦法就是開啟OS彈框,去處理彈框。有兩種方法一種通過pywin32上傳(這種只支援python語言),另一種是通過autoit上傳(python和java都支援,其他的沒有實踐過)。這裡我們只會講到autoit上傳檔案。
4.1非input控制元件上傳檔案
巨集哥總結了一下,大體上有以下幾種解決方案:
(1)autoIT,藉助外力,我們去呼叫其生成的au3或exe檔案。
(2)Python pywin32庫,識別對話方塊控制程式碼,進而操作
(3)SendKeys庫
(4)keybd_event,跟3類似,不過是模擬按鍵,ctrl+a,ctrl+c, ctrl+v…
5.準備工作
關於檔案上傳,巨集哥前邊已經介紹過幾種方法了,今天這篇介紹一個第三方工具,叫AutoIt,簡單來說,這個是一個能支援桌面GUI自動化的工具,它支援指令碼語言編寫。這裡,我們用AutoIt來做檔案上傳的演示。在Selenium指令碼中如果需要AutoIt來協助這個檔案上傳功能,大概步驟是這樣的:
1.Selenium點選web產品上的檔案上傳按鈕,彈窗上傳框。
2.執行AutoIt實現準備好的指令碼檔案,這個指令碼檔案寫了關於上傳什麼檔案的一個.exe檔案。
所以,我們先來介紹如何下載和安裝AutoIt。
5.1下載和安裝AutoIt
檔案上傳是自動化中棘手的部分,目前selenium並沒有提供上傳的實現api,所以知道藉助外力來完成,如AutoIt、sikuli。
AutoIt , 這是一個使用類似BASIC指令碼語言的免費軟體,它設計用於Windows GUI(圖形使用者介面)的自動化操作,利用模擬鍵盤按鍵,滑鼠移動和視窗/控制元件的組合來實現自動化任務;
1.開啟AutoIt的官網下載
AutoIt下載連結:https://www.autoitscript.com/site/autoit/downloads/ 或者點選下列圖示進行下載!
2.點選下載zip
兩種下載方法都可以,這裡我想下載的是zip,解壓出來如下圖所示:
5.2上傳指令碼的編寫
1.點選SciTe資料夾,我們開啟指令碼編輯器。
2.開啟百度圖片上傳視窗,開啟AutoIt Windows Info 工具,滑鼠移動到Finder Tool,按住滑鼠左鍵拖動到需要識別的windows控制元件上。拖動元素定位器上那個靶點形狀按鈕到檔案上傳彈窗,能夠捕獲到一些元素資訊。用滑鼠拖住工具上的Finder Tool的圖示(即圖中藍色圈圈部分)到要識別的控制元件上,控制元件的唯一標識資訊會顯示在工具的左側部分(圖中紅框標出的部分)。從顯示的結果得知,此控制元件的Title=“開啟”,Class為Edit,Instance=1。我們就是利用控制元件的這些資訊,定位控制元件,編寫指令碼。
3.開啟編輯器,根據控制元件Finder Tool識別到的資訊來呼叫函式編寫指令碼;在AutoIt指令碼編輯器裡輸入如下指令碼,不要下面我寫的備註哈。
我們這裡需要知道有以下資訊:
1.操作頁面的title,用於固定操作的頁面。
2.需要填入的資訊,在輸入框中填入“上傳檔案的路徑及檔名”(windows操作)
3.點選“開啟”按鈕,實現檔案上傳。
根據以上所識別的控制元件資訊,利用編輯器SciTE Script Editor,根據AutoIT的語法編寫指令碼。
實現檔案上傳需要的幾個方法:
ControlFocus ( "視窗標題", "視窗文字", 控制元件ID) ---->設定輸入焦點到指定視窗的某個控制元件上(即:控制元件ID“檔名”輸入框的id) WinWait ( "視窗標題" [, "視窗文字" [, 超時時間]] ) ---->暫停指令碼的執行直至指定視窗存在(出現)為止 ControlSetText ( "視窗標題", "視窗文字", 控制元件ID, "新文字" ) ---->修改指定控制元件的文字(即:控制元件ID“檔名”輸入框的id) Sleep ( 延遲 ) ---->使指令碼暫停指定時間段 ControlClick ( "視窗標題", "視窗文字", 控制元件ID [, 按鈕] [, 點選次數]] ) ---->向指定控制元件傳送滑鼠點選命令(即:控制元件ID“開啟”按鈕的id)
其中,title即AutoIt Window Info識別出的Title欄位,controlID即AutoIt Window Info識別出的Class和Instance的拼接,如上圖拼接後的結果應為:Button1(即classnameNN)
;ControlFocus(("title","text",controllD)用於識別windows檔案上傳視窗 ControlFocus("開啟","","") ;向檔名輸入框輸入本地要上傳檔案的路徑 ControlSetText("開啟","","Edit1","C:\Users\DELL\Desktop\test\upload\北京巨集哥.jpeg") Sleep(2000) ;點選上傳視窗中的“開啟“按鈕 ControlClick("開啟","","Button1")
5.3驗證上傳指令碼是否正確
1.儲存指令碼檔案為ChromFileUpload.au3格式,然後在AutoIt指令碼編輯器中點選Tools選單,tools=>go,執行指令碼驗證(前提是windows視窗必須是開啟狀態),驗證成功,如下圖所示:
5.4上傳指令碼編譯成一個.exe檔案
為了這個指令碼能被java 程式呼叫,需要通過Compile Script to .exe (x64)工具生成exe檔案(這個是通過.exe安裝包安裝的AutoIt)
1.AutoIt指令碼編輯器中點選Tools選單,選擇compile,會在同路徑下生成一個.exe的檔案(這個是通過解壓包安裝的AutoIt)
2.提示Conversion complete轉化完成:將ChromeFileUpload.exe拷貝到專案下,待會在Selenium指令碼要使用。
5.5java程式碼執行exe檔案
//實現檔案上傳。通過Runtime的靜態方法獲取Runtime物件 Runtime runtime = Runtime.getRuntime(); //通過Runtime物件呼叫exe方法 runtime.exec("C:\Users\DELL\Desktop\test\upload\ChromeFileUpload.exe");
6.專案實戰
6.1程式碼設計
實現檔案上傳整體程式碼如下:
6.2參考程式碼
package lessons; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; /** * @author 北京-巨集哥 * * @公眾號:北京巨集哥 * * @《手把手教你》系列技巧篇(五十三)-java+ selenium自動化測試-上傳檔案-下篇(詳細教程) * * 2021年12月9日 */ public class AutoItUpload { public static void main(String[] args) { System.setProperty("webdriver.gecko.driver", ".\\Tools\\chromedriver.exe"); //指定驅動路徑 WebDriver driver =new ChromeDriver(); try { driver.get("https://www.baidu.com"); driver.manage().window().maximize(); // 點選照相機這個按鈕 driver.findElement(By.xpath("//*/span[@class='soutu-btn']")).click(); // 點選本地上傳圖片 driver.findElement(By.xpath("//*/input[@class='upload-pic']")).click(); Thread.sleep(3000); //實現檔案上傳。通過Runtime的靜態方法獲取Runtime物件 Runtime runtime = Runtime.getRuntime(); //通過Runtime物件呼叫exe方法 runtime.exec("C:/Users/DELL/Desktop/test/upload/ChromFileUpload.exe"); Thread.sleep(5000); }catch (Exception e) { e.printStackTrace(); }finally { System.out.println("執行結束,關閉瀏覽器"); driver.quit(); } } }
6.3執行程式碼
1.執行程式碼,右鍵Run AS->Java Appliance,控制檯輸出,如下圖所示:
2.執行程式碼後電腦端的瀏覽器的動作,如下小視訊所示:
7.小結
這樣,我們就實現了利用AutoIt的自動上傳功能。好了,今天時間也不是很早了,巨集哥今天就講解和分享到這裡,感謝您耐心的閱讀