python關於威尼斯人平臺搭建win32api與ImageGrab.grab()截屏少內容的問題
系統環境:win7 x64
項目介紹:使用pyautogui對pc端應用程序做自動化操作。
項目一開始使用的pyautogui.locateOnScreen("xxx.png")來定位,使用pyautogui.click()來實現點擊,使用typewrite("xxx")來實現文本的輸入。
本身項目難度不大,但是問題就出在生產環境下locateOnScreen()定位不到彈窗內容,一開始以為是cpu等硬件問題,導致截圖延遲造成的(畢竟locateOnScreen的效率還是挺低的,一般全屏識別需要3-6s的時間)。所以就想著先把圖片截取下來,然後再用locate本地對比識別。
隨後就采用pyautogui.screenshot()來截屏,但是發現還是不行,當時認為是截取的太快了,因為screenshot的還是挺快的,1920*1080的截屏也只需要100ms,擔心是tooltip(懸浮提示)還沒有出來就截屏了,所以就加了time.sleep(1)來延遲截屏。但是結果還是沒有東西,就想到是不是這個函數是異步處理的,不會等待sleep的執行完成,在這裏走了一些彎路。
翻看了pyautogui的源碼,發現screenshot在win下采用的是PIL的ImageGrab.grab()來實現的截屏。就用PIL模擬了一下screenshot的過程,結果還是截取不到tooltip。隨後用了win32api的截圖方法,結果還是截取不到。顯然用win32api的效率已經是非常高了,當時又加了一些延遲,但是還是不行。
# import time # import win32gui,win32ui,win32con,win32api # def window_capture(filename): # hwnd=0 # hwndDC=win32gui.GetWindowDC(hwnd) # mfcDC = win32ui.CreateDCFromHandle(hwndDC) # saveDC=mfcDC.CreateCompatibleDC() # saveBitMap=win32ui.CreateBitmap() # MoniterDev=win32api.EnumDisplayMonitors(None,None) # w=MoniterDev[0][2][2] # h=MoniterDev[0][2][3] # saveBitMap.CreateCompatibleBitmap(mfcDC,w,h) # saveDC.SelectObject(saveBitMap) # saveDC.BitBlt((0,0),(w,h),mfcDC,(0,0),win32con.SRCCOPY) # saveBitMap.SaveBitmapFile(saveDC,filename) # window_capture("2.png")
最後無奈,只好手動測試,到底為什麽沒有截取到(截至目前,沒不知道原因是截取不到,一直還認為可能是延遲、程序異步的問題)。為了方便記錄截圖的時間,所以就想到了用個小工具顯示再屏幕上,找工具太麻煩,就用了win7的小工具--時鐘。這個就是問題的突破口。用了這個之後,發現之前的程序都截取不到這個小工具。又經過一系列的測試斷定是截圖函數的問題。
測試使用prtsc截圖快捷鍵可以。所以才有了最後的方案,同樣是采用win32api,但是需要用到快捷鍵截屏,並且需要用到剪切板來存儲截圖。
win32api.keybd_event(win32con.VK_SNAPSHOT, 0)
time.sleep(0.5)
im=ImageGrab.grabclipboard()
im.save("screen.png")
問題解決,用時5-6個小時。
python關於威尼斯人平臺搭建win32api與ImageGrab.grab()截屏少內容的問題