手把手教你使用pyautogui


最近公司項目需要,要在三百多台終端上測一個windows軟件的兼容性,所以想做個UI自動化,於是看到了pyautogui這個包,從名字就能看出,他是做gui界面相關的包,
pyautogui最方便的地方就是,你不需要去用代碼定位元素,你只需要用截圖就行,例如你要識別桌面上某個應用,你只需要截圖這個應用,然后通過這個截圖和當前桌面對比即可找到圖標的位置,說到這里,大家應該就會想到,那我是不是把代碼封裝好之后,后面不管產品怎么迭代,我只要更換截圖就可以了?是的!這就是我在這里寫篇博客的目的,我看了一下,基本沒有一個完整的源碼教程,所以我想給大家分享一個完完整整的教程,因為他是真的好用,代碼簡單,后期維護成本低。
首先是基本用法,這個百度一下一大堆,這里是pypi的文檔,自行閱讀:https://pypi.org/project/PyAutoGUI/
簡單的貼兩行官方文檔中代碼:

import pyautogui
pyautogui.moveTo(100, 150) # Move the mouse to the x, y coordinates 100, 150.
pyautogui.click()

上面就是一個把鼠標移到(100,150)這個坐標的代碼,並且左鍵鼠標單擊,當然有鼠標單擊就有雙擊,各種操作查看上面文檔即可,那我們如何定位我們想要的內容在哪呢?請繼續往下看:

假設我們想要定位“計算機”的坐標然后去點擊他,可以通過如下代碼:

#這是你的目標圖標,也就是你的截圖,下面找他的時候會用到
appname = ROOT_DIR + '/testimage/' + target + '.png'
##根據桌面路徑進行截屏
##獲取當前桌面路徑
threshold = 0.85
path = os.path.join(os.path.expanduser('~'), "Desktop")
hwnd = win32gui.FindWindow(None, path)
app = QApplication(sys.argv)
screen = QApplication.primaryScreen()
img = screen.grabWindow(hwnd).toImage()
# img = ImageGrab.grab()

##保存截屏
root_desk = ROOT_DIR + '/desktop.png'
img.save(root_desk)
##等待圖片保存
time.sleep(0.5)
# 支持圖片名為中英文名,也支持路徑中英文
imsrc = cv2.imdecode(np.fromfile(root_desk, dtype=np.uint8), -1)
imobj = cv2.imdecode(np.fromfile(appname, dtype=np.uint8), -1)

# 匹配圖標位置
pos = ac.find_template(imsrc, imobj, threshold)

pos就是當前匹配到的路徑
這是基本用法,其他方法可以在我后面的源碼中查看

下面說坑:
1.python和第三方包版本
之前使用的是python2,於是去安裝對應的py包,結果一頓騷造作之后,發現總是有問題,鼠標老是移動不到目標坐標位置,於是換了py3.6版本和對應的依賴包,搞定
2.windows用戶權限彈框

你沒看錯,就是這個玩意,能匹配到,但是不能點擊,最后直接把這個彈框在windows系統上禁用了,如果你有好的辦法,可以聯系我,一起共享
3.突然操作失效,例如定位坐標出錯,點擊不了鼠標
這個解決辦法有點呵呵,重啟電腦,然后再運行代碼,嗯,沒問題了,wtf

說完坑,然后說如何做到前面說的只需要維護截圖就能更新迭代。

1、定義好你的操作和對應的函數。
在py文件里面添加如下代碼:

ACTIONCN2EN = {"匹配": "match", "輸入內容": "input_type", "復制入內容": "input_copy", "左鍵單擊": "click_once",
               "左鍵雙擊": "click_twice", "Enter鍵單擊": "click_enter_once", "等待出現": "wait", "全選": "select_all",
               '點擊按鍵': 'type_write', '檢測結果': 'check_result', '鼠標滾動': 'scroll'}
@time_sleep
def click_once():
    pyautogui.click()

上面我就舉一個鼠標左鍵點擊一次的例子,節約篇幅
然后定義動作,這里新建一個txt文件:
里面輸入如下:

定義好之后,可以用python打開這個txt文件,然后通過eval(ACTIONCN2EN[act])(params)去執行函數即可
如果想要其他的步驟,直接在后面添加即可,例如我以->作為分隔符,定義了如下測試流程:

通過如下代碼即可解析步驟:

with open(file, encoding='utf-8') as f:
action_str = f.read()

# 保證'動作.txt'里,動作最后的換行符無影響
action_str = action_str.strip('\n')
# 保證動作之間的單個換行符跟->等效。若有多個換行符,放到if act=''里
action_str = action_str.replace('\n', '->')
# print(action_str)
action_list = action_str.split('->')
for act in action_list:
if act == '':  # 當同時有多個換行符時,act就是空,在這里排除
    pass
else:
    try:  # 防止同一Dj99ZzZz個action里,有一個動作異常就不執行其他動作
        act.encode('utf-8')
        ##提取action具體動作的括號里的內容,如match(QQ-單發輸入框)
        p1 = re.compile(r'[(](.*?)[)]', re.S)
        params = re.findall(p1, act)  # 查找后返回list,都放在[0]里,()內無東西,即無參數,返回空列表
        act = act.split('(')[0]

        if params == []:
            print(u"調用方法為:{}".format(act))
            eval(ACTIONCN2EN[act])()
        else:
            params = params[0]
            if params == 'arg1':
                try:
                    params = sys.argv[1]
                except IndexError as ex:
                    raise Exception('請傳第1個參數')
            if params == 'arg2':
                try:
                    params = sys.argv[2]
                except IndexError as ex:
                    raise Exception('請傳第2個參數')
            print(u"調用方法為:{}({})".format(act, params))
            eval(ACTIONCN2EN[act])(params)  # 參數可以有多個,參數之間用,分隔。目前只支持一個參數
    except Exception as e:
        print(e)
        break

然后根據動作,截圖好每個圖標就可以,下次產品迭代或者新增功能,直接更新action.txt文件的步驟和截圖就行了
github代碼地址:https://github.com/ruhaoyu/uitest


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM