赞
踩
本博客仅为个人学习使用,是看大佬视频做的笔记,侵权可联系作者删除~~
from pywinauto.application import Application # 通过pywinauto去连接已经打开的应用程序 # 通过进程号进行连接,可以使用ViewWizard查看进程号等信息 # 通过PID连接,需要先打开程序 # app = Application('uia').connect(process=6136) # print(app) # 通过窗口句柄进行连接 # 同样需要先打开程序,然后使用ViewWizard获取句柄,句柄是动态的 app = Application('uia').connect(handle=131914) ''' 这个uia,在启动navicat的时候需要,不然报错; 启动文本文件的时候不用,不然找不到弹出的窗口 初步推论:win32(可不填)在自带程序中使用,其他需下载安装等程序使用uia Win32 API(backend="win32") - 现在的默认后端 MFC,VB6,VCL,简单的WinForms控件和大多数旧的遗留应用程序,win32 MS UI Automation(backend="uia") WinForms,WPF,商店应用,Qt5,浏览器,navicat 注意:Chrome --force-renderer-accessibility在启动前需要cmd标志。 由于comtypes Python库限制,不支持自定义属性和控件。''' print(app)
from pywinauto.application import Application # 启动navicat,路径也可以通过ViewWizard工具获取 app = Application('uia').start(r'E:\Navicat Premium 15\navicat.exe') # 方式一 app[类名/标题] # 使用窗口类名来选择窗口 # dlg = app["TNavicatMainForm"] # 使用窗口标题来选择窗口 dlg = app['Navicat Premium'] dlg.maximize() # 方式二 app.窗口类名 # dlg = app.TNavicatMainForm # 打印窗口中所有的控件 # dlg.print_control_identifiers()
from pywinauto.application import Application # 启动navicat app = Application('uia').start(r'D:\tools\Navicat Premium 15\navicat.exe') # 通过窗口标题选择窗口 dlg = app['Navicat Premium'] # dlg.print_control_identifiers() # 选择控件 ---- 选择当前窗口的各级菜单 # 方式一 # menu = dlg.Menu # print(menu.print_control_identifiers()) # 方式二 menu = dlg['Menu'] # print(menu.print_control_identifiers()) # ------报错------------ # file = dlg['Menu']['文件'] # print(file.print_control_identifiers()) # 方式三 # menu下面的中括号显示的是['MenuItem', '文件MenuItem', '文件', 'MenuItem0', 'MenuItem1'] # 文件是第一个子菜单,根据菜单名查找就好,不用管中括号里面有几个 file = menu.child_window(title="文件", control_type="MenuItem") file.print_control_identifiers()
from pywinauto.application import Application # 启动navicat,选择应用程序 app = Application('uia').start(r'D:\tools\Navicat Premium 15\navicat.exe') # 通过窗口标题选择窗口 dlg = app['Navicat Premium'] # 选择窗口的菜单 menu = dlg['Menu'] # 选择菜单项:文件 file = menu.child_window(title="文件") # 查看控件类型:wrapper_object # print(dlg.wrapper_object()) # Dialog 对话框 # print(menu.wrapper_object()) # Menu 菜单 # print(file.wrapper_object()) # MenuItem 菜单项 # dir 查看对象所支持的方法 # print(dir(dlg.wrapper_object())) # 控件的文本内容获取:texts --- 得到的是列表 print(file.texts()) # 获取子元素:children # print(dlg.children()) # 获取菜单的子元素 # print(menu.children()) # print(file.children()) # 获取控件的类名 print(menu.class_name()) # 获取控件的属性、返回的字典 print(menu.get_properties())
from pywinauto.application import Application # 启动navicat app = Application('uia').start(r'E:\Navicat Premium 15\navicat.exe') # 通过窗口标题选择窗口 dlg = app['Navicat Premium'] menu = dlg['Menu'] # # # 选择菜单项:文件 file = menu.child_window(title="文件") # 截图窗口: pic = dlg.capture_as_image().save('01.png') print(pic)
# 点击菜单项用click_input(),点击按钮可直接用click() from pywinauto.application import Application app = Application('uia').start(r'E:\Navicat Premium 15\navicat.exe') dlg = app['Navicat Premium'] menu = dlg['Menu'] file = menu.child_window(title="文件", control_type="MenuItem") # -------菜单控件和相关操作--------------- # 获取菜单的子菜单项 # print(menu.items()) # 通过下标去选择菜单项:item_by_path # m = menu.item_by_index(1) # print(m) # 通过路径去选择菜单项:item_by_path ,相对路径 # m = menu.item_by_path('查看') # print(m) # 通过路径去选择菜单项:item_by_path ,相对路径 # m = menu.item_by_path('文件->导入连接...') # print(m) # ----- 菜单项的操作方法----- # 获取子菜单项:items # print(file.items()) # 点击菜单项的方法:click_input # 注意:先点击文件,然后点击新建连接 file.click_input() menu.item_by_path('文件->新建连接').click_input()
from pywinauto.application import Application app = Application('uia').start(r'E:\Navicat Premium 15\navicat.exe') dlg = app['Navicat Premium'] menu = dlg['Menu'] # menu.print_control_identifiers() file = menu.child_window(title="文件", control_type="MenuItem") # 点击文件 file.click_input() # 点击新建连接 menu.item_by_path('文件->新建连接').click_input() ''' 等待机制一 wait方法: 等待窗口处于某个状态 参数: wait_for :等待的状态(状态有以下几种) exists: 表示该窗口是有效的句柄 visible:表示该窗口未隐藏 enabled:表示未禁用窗口 ready:表示该窗口可见并启用 active:表示该窗口处于活动状态 timeout : 超时时间 retry_interval :重试时间间隔 ''' # 选择新建连接的窗口 new_dlg = app['新建连接'] # 等待窗口处于可见状态 # new_dlg.wait(wait_for="ready", timeout=10, retry_interval=1) # print('等待通过,当前新建连接窗口处于可见状态') ''' 等待机制二 Wait_not方法: 等待窗口不处于某个特定状态 参数: wait_for_no :等待的状态(状态有以下几种) exists: 表示该窗口是有效的句柄 visible:表示该窗口未隐藏 enabled:表示未禁用窗口 ready :表示该窗口可见并启用 active:表示该窗口处于活动状态 timeout : 超时时间 retry_interval :重试时间间隔 ''' new_dlg.wait_not(wait_for_not="ready", timeout=10, retry_interval=1) print('等待通过,当前新建连接窗口处于不可见状态') ''' 等待机制三 wait_cpu_usage_lower 方法 等待该进程的cup的使用率低于某个阀值 注意:此方法仅适用于整个应用程序进程,不适用于窗口/元素。 参数: threshold :该进程cup占用率 timeout : 超时时间 retry_interval :重试时间间隔 ''' app1 = Application().connect(process=8728) app1.wait_cpu_usage_lower(threshold=5, timeout=5, usage_interval=1) print('等待通过,当前该进程cpu占用了低于1%')
from pywinauto.timings import wait_until ''' timings模块 wait_until方法: 参数: Timeout: 超时时间 retry_interval 重试时间 func 执行的函数 value 比较的值 Op 比较方式函数(默认为相等) args 给执行函数传位置参数 kwargs 给执行函数传关键字参数 ''' ''' 全局计时变量值的设置方法 Timings.defaults() :将全局计时设为默认值 Timings.slow() :将所有时间加倍(使脚本执行速度降低约2倍) Timings.fast(): # 将所有计时除以2 (快2倍) ''' i = 0 def work(): global i i += 1 print('当前i的值为:' , i) return i # 等待work返回的结果为5,继续往下执行 # wait_until(10, 1, work, 5) # print('等待通过') wait_until(10, 1, work, 15) print('等待超时')
from pywinauto.application import Application from pywinauto.keyboard import send_keys # 选择应用程序 app = Application('win32').start('notepad.exe') # app = Application('uia').start('notepad.exe') # 不使用uia,因为文本文件是自带程序 # 选择窗口 dlg = app['无标题 - 记事本'] # dlg.print_control_identifiers() # 选择窗口中的控件 dlg['Edit'].type_keys("hello world,哈哈?为什么空格不能显示为什么??") # menu.print_control_identifiers() # 为啥不用点击编辑,就可以直接点击替换啊?奇怪 # edit_btn = menu.child_window(title="编辑(E)", control_ty pe="MenuItem") # edit_btn.click_input() # 写法二、dlg.menu_select('编辑(E)->替换(R)') 有时候会不可用 dlg.menu_select('编辑(E)->替换(R)') # 写法一、menu.item_by_path('编辑(E)->替换(R)').click_input() # 切换到替换的窗口 replace = app['替换'] replace.print_control_identifiers() # 输入查找内容 replace['Edit1'].type_keys('哈') # 输入需要替换的内容 replace['Edit2'].type_keys('嗯哼') # 点击全部替换 replace['Button3'].click_input() # 点击取消按钮 replace['Button4'].click_input()
from pywinauto.keyboard import send_keys
# send_keys("{F1}")
# 通过按键打开cmd,输入python
send_keys('{VK_LWIN}cmd{VK_RETURN}{VK_RETURN}')
send_keys('python')
send_keys('{VK_RETURN}')
from pywinauto.keyboard import send_keys
'''
"+" --> 按Shift
"^" --> 按CtrI
"%" --> 按Alt
"^s" --> 按CtrI+S进行保存的操作
'''
send_keys('^a')
send_keys('^c')
send_keys('^v')
send_keys('^v')
send_keys("%+{VK_F10}")
from pywinauto import mouse # 鼠标单击(默认左键) # 默认button左键点击,coords参数为像素,可用截图查看 # mouse.click(button='left',coords=(485, 18)) # 鼠标右键 # mouse.right_click(coords=(1060, 580)) # 鼠标双击(默认双击左键) # mouse.double_click(button='left', coords=(48, 176)) # 点击鼠标中键 # mouse.wheel_click(coords=(500, 1000)) # 按下鼠标(会一直按住,移动鼠标即可实现拖动效果) # mouse.press(coords=(80, 20)) # 释放鼠标(位置A按下,位置B释放,即可实现拖动到位置B的效果) # mouse.release(coords=(500, 1000)) # 滑动鼠标滚轮(wheel_dist滚轮滚几圈,正数向上滚,负数向下滚) # mouse.scroll(coords=(1000, 500),wheel_dist=3) # 移动鼠标位置--将鼠标移动到某个位置 # mouse.move(coords=(0, 0)) for i in range(0, 1000, 50): mouse.move(coords=(i, i))
from pywinauto import Application
app = Application("uia").connect(handle=65722)
# 不知道为什么这行报错,跟老师代码一模一样的
app["任务栏"].print_control_identifiers()
# 到任务栏中选择用户提示通知区域,点击QQ
qq = app["任务栏"].child_window(title="QQ: 慎\r\n声音: 关闭\r\n消息提醒框: 关闭\r\n会话消息: 任务栏头像闪动", control_type="Button")
qq.click()
from pywinauto import Application
app = Application("uia").connect(handle=65722)
task = app["任务栏"].child_window(title="通知 V 形", auto_id="1502", control_type="Button")
task.click()
#选择通知溢出的窗口,然后就可以进行相关的操作
# 隐藏区域需要先点击然后对应的窗口才会显示,可以使用inspect.exe工具
app["通知溢出"].print_control_identifiers()
app["通知溢出"]["Windows 安全中心"].click()
from selenium import webdriver from pywinauto.keyboard import send_keys import pywinauto from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get(r'http://XXX.baidu.com/uploadimg?picIdFlag=pic02&category_id=1') # 点击上传图片按钮 driver.find_element(By.ID,'btnSelect').click() # 上传图片弹出的窗口需要用pywinauto选择图片 app = pywinauto.Desktop() dlg = app["打开"] dlg.print_control_identifiers() # 选中文件地址输入的工具框, # 因为不是输入框不能直接输入,需要通过键盘输入 # 输入文件地址 dlg['Toolbar3'].click() send_keys("图片{VK_RETURN}") # 输入图片名 dlg['Edit'].click() send_keys("壁纸.jpg{VK_RETURN}")
# Button类型的就可以直接调用click() from selenium import webdriver from pywinauto.keyboard import send_keys import pywinauto from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get(r'http://XXXX.baidu.com/uploadimg?picIdFlag=pic02&category_id=1') # 点击上传图片按钮 driver.find_element(By.ID, 'btnSelect').click() def upload_img(file_path, file, *args): # 上传图片弹出的窗口需要用pywinauto选择图片 app = pywinauto.Desktop() dlg = app["打开"] dlg.print_control_identifiers() # 选中文件地址输入的工具框, # 因为不是输入框不能直接输入,需要通过键盘输入 # 输入文件地址 dlg['Toolbar3'].click() send_keys(file_path) # 输入图片名 dlg['Edit'].click() dlg['Edit'].type_keys(f'"{file}"') for i in args: # 选择多个文件 send_keys(f'"{i}"') dlg['打开(&O)'].click() upload_img("图片{VK_RETURN}", "壁纸.jpg", "壁纸2.jpg")
# 实现navicat的新建连接功能 from pywinauto.application import Application # app = Application('uia').start(r'E:\Navicat Premium 15\navicat.exe') # 为了不每次都重新打开navicat,运行一次打开新建连接页面后,使用句柄进行连接即可 app = Application('uia').connect(handle=526170) dlg = app['Navicat Premium'] # # 选择菜单栏 menu = dlg["Menu"] # menu.print_control_identifiers() # # 点击文件 # 不可用 --> menu['文件'].click_input() file = menu.MenuItem1 file.click_input() # 与上面的方法一样 # file = menu.child_window(title="文件", control_type="MenuItem") # file.click_input() # 报错 --- menu.child_window(title="新建连接", control_type="MenuItem").click_input() # # 点击新建连接 menu.item_by_path("文件->新建连接").click_input() # 只是使用这个不行,需要先点击文件,然后点击新建连接,然后点击mysql才行 menu.item_by_path("文件->新建连接->MySQL...").click_input() # ================================================= # 填写连接数据 # 选择新建连接窗口 # dlg.print_control_identifiers() dlg["Pane2"].print_control_identifiers() # 连接名 dlg["常规"].Edit5.type_keys("测试新建连接") # ip输入框 # new_dlg["常规"]["Edit1"],报错,此时应该更换.的方式 dlg["常规"].Edit1.type_keys("127.0.0.1") # 端口输入框 dlg["常规"].Edit4.type_keys("3306") # 用户名输入框 dlg["常规"].Edit3.type_keys("root") # 密码输入框 dlg["常规"].Edit2.type_keys("123456") # 点击确定按钮,Button类型的就可以直接调用click() dlg["确定"].click()
# 重要:当控件不能点击的时候获取位置进行点击 # 实现点击新建成的连接, # 因为该数据库是treeView不可点击的,所以要通过鼠标定位点击 import pywinauto from pywinauto import mouse # 根据PID选择程序 app = pywinauto.Application(backend="uia").connect(handle=131914) # 根据窗口标题选择窗口 dlg = app["Navicat Premium"] # dlg.print_control_identifiers(depth=3) # 选择树状视图控件 # [TVTFilterFrame][TPanel][TNavicatMainForm][#32769] # dlg["TTreeView"].print_control_identifiers() dlg["TPanel"].print_control_identifiers() # 点击连接 db_name = dlg["TVirtualStringTree"].child_window(title="测试新建连接", control_type="TreeItem") # db_name.click() # 会报错,不可以点击 # rectangle() 获取控件上下左右的位置;mid_point()获取中心点的位置 rect = db_name.rectangle().mid_point() print(rect.x, rect.y) mouse.double_click(rect.x, rect.y)
# 重要:点击后出现的窗口用viewwizard定位时消失的处理方法 # 就是通过app.windows()获取当前应用程序的所有窗口定位 # 实现点击删除连接,如何定位到该应用程序的其他窗口 from pywinauto import Application from pywinauto import mouse # 根据PID选择程序 app = Application("uia").connect(process=4176) # 根据窗口标题选择窗口 dlg = app["Navicat Premium"] # 选择树状视图控件 dlg["TTreeView"].print_control_identifiers() # 点击连接 db_name = dlg["TTreeView"].child_window(title="测试新建连接", control_type="TreeItem") # db_name.click() # 会报错,不可以点击 # rectangle() 获取控件上下左右的位置;mid_point()获取中心点的位置 rect = db_name.rectangle().mid_point() print(rect.x, rect.y) # 鼠标在控件中心点,右击 mouse.right_click(coords=(rect.x, rect.y)) # 获取该应用程序的所有窗口 print(app.windows()) # 选择右击出现的上下文窗口 # app["上下文"].print_control_identifiers() # 打开连接 # app["上下文"]["MenuItem1"].click_input() # 删除连接 app["上下文"]["MenuItem5"].click_input() # 选择删除窗口 app["确认删除"]["删除"].click()
# 将连接的动作封装起来 from pywinauto.application import Application from pywinauto import mouse class NavicatTest: def __init__(self, path=None, precess=None): if path: self.app = Application('uia').start(path) else: # 为了不每次都重新打开navicat,运行一次打开新建连接页面后,使用句柄进行连接即可 self.app = Application('uia').connect(handle=12) self.dlg = self.app['Navicat Premium'] def new_connect(self): menu = self.dlg["Menu"] # 点击文件 menu.child_window(title="文件").click_input() # 点击新建连接 menu.item_by_path("文件->新建连接").click_input() # 选择新建连接窗口 new_dlg = self.app["新建连接"] # 连接名 new_dlg["常规"].Edit5.type_keys("1111") # ip输入框 # new_dlg["常规"]["Edit1"],报错,此时应该更换.的方式 new_dlg["常规"].Edit1.type_keys("1111") # 端口输入框 new_dlg["常规"].Edit4.type_keys("1111") # 用户名输入框 new_dlg["常规"].Edit3.type_keys("1111") # 密码输入框 new_dlg["常规"].Edit2.type_keys("1111") # 点击确定按钮,Button类型的就可以直接调用click() new_dlg["确定"].click() def open_connect(self): # 根据窗口标题选择窗口 # self.dlg = self.app["Navicat Premium"] # 选择树状视图控件 self.dlg["TTreeView"].print_control_identifiers() # 点击连接 db_name = self.dlg["TTreeView"].child_window(title="测试新建连接", control_type="TreeItem") # db_name.click() # 会报错,不可以点击 # rectangle() 获取控件上下左右的位置;mid_point()获取中心点的位置 rect = db_name.rectangle().mid_point() print(rect.x, rect.y) mouse.double_click(rect.x, rect.y) def del_connect(self): # 选择树状视图控件 self.dlg["TTreeView"].print_control_identifiers() # 点击连接 db_name = self.dlg["TTreeView"].child_window(title="测试新建连接", control_type="TreeItem") # rectangle() 获取控件上下左右的位置;mid_point()获取中心点的位置 rect = db_name.rectangle().mid_point() # 鼠标在控件中心点,右击 mouse.right_click(coords=(rect.x, rect.y)) # 获取该应用程序的所有窗口 # print(self.app.windows()) # 删除连接 self.app["上下文"]["MenuItem5"].click_input() # 选择删除窗口 self.app["确认删除"]["删除"].click() nav = NavicatTest(precess=12) nav.new_connect()
from pywinauto.application import Application from pywinauto import mouse class NavicatTest: def __init__(self, path=None, precess=None): if path: self.app = Application('uia').start(path) else: # 为了不每次都重新打开navicat,运行一次打开新建连接页面后,使用句柄进行连接即可 self.app = Application('uia').connect(handle=12) self.dlg = self.app['Navicat Premium'] def new_connect(self, title, host, port, user, password): '''新建连接''' menu = self.dlg["Menu"] # 点击文件 menu.child_window(title="文件").click_input() # 点击新建连接 menu.item_by_path("文件->新建连接").click_input() # 选择新建连接窗口 new_dlg = self.app["新建连接"] # 连接名 new_dlg["常规"].Edit5.type_keys(title) # ip输入框 # new_dlg["常规"]["Edit1"],报错,此时应该更换.的方式 new_dlg["常规"].Edit1.type_keys(host) # 端口输入框 new_dlg["常规"].Edit4.type_keys(port) # 用户名输入框 new_dlg["常规"].Edit3.type_keys(user) # 密码输入框 new_dlg["常规"].Edit2.type_keys(password) # 点击确定按钮,Button类型的就可以直接调用click() new_dlg["确定"].click() def open_connect(self, db_name): '''打开连接 打开连接和打开数据库的方法是一样的, 参数传数据库即可打开数据库,传连接名即可打开连接''' # 根据窗口标题选择窗口 # self.dlg = self.app["Navicat Premium"] # 选择树状视图控件 self.dlg["TTreeView"].print_control_identifiers() # 点击连接 db_name = self.dlg["TTreeView"].child_window(title=db_name, control_type="TreeItem") # db_name.click() # 会报错,不可以点击 # rectangle() 获取控件上下左右的位置;mid_point()获取中心点的位置 rect = db_name.rectangle().mid_point() print(rect.x, rect.y) mouse.double_click(rect.x, rect.y) def del_connect(self, title): '''删除连接''' # 选择树状视图控件 self.dlg["TTreeView"].print_control_identifiers() # 点击连接 db_name = self.dlg["TTreeView"].child_window(title=title, control_type="TreeItem") # rectangle() 获取控件上下左右的位置;mid_point()获取中心点的位置 rect = db_name.rectangle().mid_point() # 鼠标在控件中心点,右击 mouse.right_click(coords=(rect.x, rect.y)) # 获取该应用程序的所有窗口 # print(self.app.windows()) # 删除连接 self.app["上下文"]["MenuItem5"].click_input() # 选择删除窗口 self.app["确认删除"]["删除"].click() def close_connect(self, title): '''关闭连接 关闭连接和关闭数据库的方法是一样的, 参数传数据库即可关闭数据库,传连接名即可关闭连接''' # 选择树状视图控件 self.dlg["TTreeView"].print_control_identifiers() # 点击连接 db_name = self.dlg["TTreeView"].child_window(title=title, control_type="TreeItem") # rectangle() 获取控件上下左右的位置;mid_point()获取中心点的位置 rect = db_name.rectangle().mid_point() # 鼠标在控件中心点,右击 mouse.right_click(coords=(rect.x, rect.y)) # 获取该应用程序的所有窗口 # print(self.app.windows()) # 关闭连接 self.app["上下文"]["MenuItem2"].click_input() def del_database(self, title): '''删除数据库''' # 选择树状视图控件 self.dlg["TTreeView"].print_control_identifiers() # 点击连接 db_name = self.dlg["TTreeView"].child_window(title=title, control_type="TreeItem") # rectangle() 获取控件上下左右的位置;mid_point()获取中心点的位置 rect = db_name.rectangle().mid_point() # 鼠标在控件中心点,右击 mouse.right_click(coords=(rect.x, rect.y)) # 获取该应用程序的所有窗口 # print(self.app.windows()) # 删除数据库 self.app["上下文"]["MenuItem4"].click_input() # 选择删除窗口 self.app["确认删除"]["删除"].click() nav = NavicatTest(precess=12) nav.new_connect('测试连接','127.0.0.1','3306','root','123456') nav.open_connect('测试连接') nav.del_connect("测试连接")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。