1. 程式人生 > >Python + Selenium + AutoIt 模擬鍵盤實現另存為、上傳、下載操作詳解

Python + Selenium + AutoIt 模擬鍵盤實現另存為、上傳、下載操作詳解

前言

在web頁面中,可以使用selenium的定位方式來識別元素,從而來實現頁面中的自動化,但對於頁面中彈出的檔案選擇框,selenium就實現不了了,所以就需引用AutoIt工具來實現。

AutoIt介紹

AutoIt簡單介紹下,AutoIt 目前最新是v3版本,這是一個使用類似BASIC指令碼語言的免費軟體,它設計用於Windows GUI(圖形使用者介面)中進行自動化操作。它利用模擬鍵盤按鍵,滑鼠移動和視窗/控制元件的組合來實現自動化任務。而這是其它語言不可能做到或無可靠方法實現的(例如VBScript和SendKeys)。

實現原理:

使用AutoIT下的工具去定位頁面外的元素屬性值,其次再利用AutoIT下的工具編寫合適的指令碼,然後將指令碼編譯成可執行檔案,最後在自動化實現時,直接呼叫此指令碼實現檔案的上傳、下載等操作。

備註:定位元素、編寫指令碼和編譯,需要藉助AutoIT提供的工具,但是指令碼編譯成可執行檔案後,可以直接使用。

安裝成功後會出現如下選單:

AutoIt工具使用

1.AutoIT Window Info用來識別Windows控制元件,根據識別的控制元件資訊編寫指令碼;x86為32位

2.SciTE Script Editor用來寫指令碼,並儲存為au3格式,按F5可以除錯程式碼,但需要是操作彈框(上傳/下載/另存為彈框)開啟的情況下

3.Complie Script to .exe, 將剛編寫的指令碼,編譯成可執行檔案;

4.編譯後在Python程式碼中呼叫

想必介紹到這,或多或少有所瞭解了,對AutoIT工具下的功能點也清楚了,Run Script是執行指令碼的,我們是要到Python程式碼中呼叫,所以此處就略過了。

例項講解

接下來就用一個例項來講解下AutoIT工具的具體使用,例項功能是:把百度首頁中的百度圖片另存為到本地或任意磁碟

在做這個事情的時候,我們要知道,步驟是先要選中圖片,並右擊,選擇另存為,然後輸入檔名以及儲存的位置,最後點選儲存。人工操作滑鼠很簡單,但現在是要使用程式碼來實現該功能,可細化分為四步,如下:

1.使用Selenium功能彈出右鍵選單

2.利用win32api選擇相關選單

3.呼叫AutoIT實現另存為操作

4.到Python程式碼中呼叫

實現第一步,在瀏覽器中定位到圖片元素,程式碼如下:

context = driver.find_element_by_css_selector("
.index-logo-src") ActionChains(driver).context_click(context).perform()

實現第二步,模擬鍵盤操作,滑鼠移到另存為處,使用win32api操作,程式碼如下:

win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(13, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0)
time.sleep(1)
win32api.keybd_event(40, 0, win32con.KEYEVENTF_KEYUP, 0)
time.sleep(1)

win32api的鍵盤碼如下:

上面程式碼的13與40按鍵對應的是回車與下鍵,在鍵盤碼的圖片中很詳細

實現上述兩步程式碼後,會彈出如下所示框,讓輸入檔名以及儲存路徑,該對話方塊已經是頁面外的元素了,使用普通的定位時定不到了,所以就需要使用AutoIT工具來實現。

實現第三步,操作如下:

①開啟autoit工具包下的AutoIT Window Info(x64)工具,版本按自己電腦系統來,介面如下所示:

1.1滑鼠點中Finder Tool並拖動到輸入檔名處,操作如下所示,得到下圖結果

1.2重複上述定位步驟,定位儲存按鈕,結果如下圖所示

②元素定位到了,接下來就是使用AutoIT工具包下的SciTE Script Editor寫指令碼,並儲存為au3格式,注意:此工具中;表註釋

根據定位到的引數值,寫如下指令碼:

ControlFocus("另存為","","Edit1")
WinWait("[CLASS:#32770]","",10)
ControlSetText("另存為","", "Edit1", "G:\201801-\python_code\Demo\autoit\baidu.png")
Sleep(2000)
ControlClick("另存為","","Button2")

程式碼解釋:

第一行:ControlFocus ( "title", "視窗文字", controlID) 設定輸入焦點到指定視窗的某個控制元件上;

第二行:WinWait ( "title" , "視窗文字" , 超時時間 ) 暫停指令碼的執行直至指定視窗存在(出現) 為止;

第三行:;表註釋

第四行:ControlSetText ( "title", "視窗文字", controlID, "新文字" ) 修改指定控制元件的文字;

第五行:Sleep ( 延遲 ) 使指令碼暫停指定時間段;

第六行:ControlClick ( "title", "視窗文字", 控制元件ID , 按鈕 , 點選次數 ) 向指定控制元件傳送滑鼠點選命令;

其中, title即AutoIt Window Info識別出的Title欄位, controlID即AutoItWindow Info識別出的Class和Instance的拼接, 如上圖拼接後的結果應為:Button2,也就是ClassnameNN的值。

③使用AutoIT工具包下的Complie Script to .exe工具把剛編寫的指令碼編譯成可執行檔案,操作如下:

執行上步驟後,會出現test.exe可執行檔案,如下:

第四步,到Python程式碼中呼叫該可執行檔案,操作程式碼如下:

import os
os.system(os.getcwd() + "\\autoit\\test.exe")

執行Python程式碼,在定義的路徑下會看到已儲存的百度圖片,如下所示:

整體程式碼實現如下,僅供參考:

# coding=utf-8
from selenium import webdriver
# 滑鼠操作需要匯入ActionChains類,因為滑鼠操作的方法封裝在該類中
from selenium.webdriver.common.action_chains import ActionChains
import time
import os
import win32con
import win32api
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
time.sleep(2)
# 滑鼠右擊操作,context_click()
context = driver.find_element_by_css_selector(".index-logo-src")
ActionChains(driver).context_click(context).perform()
time.sleep(3)
# 按下下鍵
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
win32api.keybd_event(40, 0, 0, 0)
time.sleep(1)
# 按下回車
win32api.keybd_event(13, 0, 0, 0)
time.sleep(1)
# 釋放回車鍵
win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0)
time.sleep(1)
# 釋放下鍵
win32api.keybd_event(40, 0, win32con.KEYEVENTF_KEYUP, 0)
time.sleep(1)
os.system(os.getcwd() + "\\autoit\\test.exe")
# 呼叫exe檔案後,延時3秒
time.sleep(3)
driver.quit()

 將百度首頁中的圖片另存為還有一個實現方法,不用win32api操作,直接在AutoIT編寫指令碼中傳送個V,因為選擇另存為和按V是一樣的作用,AutoIT編寫指令碼程式碼如下:

send("v")
Sleep(1000)
ControlFocus("另存為","","Edit1")
WinWait("[CLASS:#32770]","",10)
ControlSetText("另存為","", "Edit1", "G:\201801-\python_code\Demo\autoit\baidu1.png")
Sleep(2000)
ControlClick("另存為","","Button2")

重複編譯操作,然後在Pyhton程式碼中實現如下,僅供參考:

# coding=utf-8
from selenium import webdriver
# 滑鼠操作需要匯入ActionChains類,因為滑鼠操作的方法封裝在該類中
from selenium.webdriver.common.action_chains import ActionChains
import time
import os
import win32con
import win32api

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
time.sleep(2)
# 滑鼠右擊操作,context_click()
context = driver.find_element_by_css_selector(".index-logo-src")
ActionChains(driver).context_click(context).perform()
time.sleep(3)
os.system(os.getcwd() + "\\autoit\\test1.exe")
time.sleep(3)
driver.quit()

執行程式碼後,圖片儲存成功,如下:

如上就是完整的將網頁圖片另存為的操作,上傳/下載的操作一樣,把另存為學會,其他兩類也就迎刃而解了。

總結:

在琢磨模擬鍵盤操作時,有兩個錯誤點,而導致編寫的程式碼與指令碼總是執行不成功,後面自己仔細查詢原因,以及百度,終於是給解決了,所以故記錄下,也好看看自己的進步過程。

問題一:

模擬按鍵操作,之前沒選對操作方式,這是自己的Python基礎薄弱,需要補充,後面找到win32api的方式,並找到鍵盤圖,按鍵操作就完美解決。

問題二:

編寫autoit的指令碼,定位後,controlID沒有拼接,而是直接寫的Edit,Button,而導致程式碼呼叫指令碼,但沒執行操作,controlID即AutoItWindow Info識別出的Class和Instance的拼接, 如上圖拼接後的結果應為:Button2,也就是ClassnameNN的值。

問題三:

在呼叫exe檔案成功並執行操作後,還沒點選儲存按鈕,瀏覽器就立馬關閉了,後面一想,在呼叫exe檔案後,加個延時就解決了,如果exe檔案執行的內容多,延時需要長些,不然driver.quit()會很快關閉瀏覽器。

好了,說了這麼多,自己需要努力的還有很多,明天中秋,祝大家中秋節快樂啦!