相关文章推荐
朝气蓬勃的咖啡豆  ·  SpringBoot ...·  8 月前    · 
好帅的西装  ·  Three-Dimensional ...·  2 年前    · 
from pywinauto.application import Application # 常用方式一:连接已有微信进程(进程号在 任务管理器-详细信息 可以查看) app = Application(backend= 'uia' ).connect(process= 8948 ) # 常用方式二:启动微信进程 (注意路径中特殊字符的转义,/和\,不注意有时会出错) app = Application(backend= "uia" ).start( r'C:\Program Files (x86)\Tencent\WeChat\WeChat.exe' ) # 结束进程 app.kill() 二、backend选择 和 控件查看工具inspect 1.backend选择和inspect介绍 我们安装好Pywinauto之后,首先要确定哪种可访问性技术(backend)可以用于我们的应用程序,在windows上受支持的有两种:

Win32 API ( backend= "win32" ) 默认的backend

MS UI Automation ( backend="uia" )

如果不能确定程序到底适用于那种backend,可以借助于GUI对象检查工具来做,常用的检查工具有 Inspect.ex Spy++ ,下载地址: https://github.com/blackrosezy/gui-inspect-tool

将inspect左上角的下拉列表中切换到“UI Automation”,然后鼠标点一下你需要测试的程序窗体,inspect就会显示相关信息,如下图所示。说明backend为uia程序里面的任意一个部位其实都是控件,在inspect的控件树中都可以找到,是一层一层分级别的,可以一个个点开所有控件

2.打印元素 我们拿到控件后,是可以将该控件下的所有子控件及其属性以树形结构打印出来的:

# 拿到微信主窗口 win_main_Dialog = app.window(class_name= 'WeChatMainWndForPC' ) # 判断是否为dialog,一个微信是一个dialog,就是窗口 print(win_main_Dialog.is_dialog) # 给控件画个红色框便于看出是哪个 win_main_Dialog.draw_outline( colour = 'red' ) # 打印当前窗口的所有controller(控件和属性) win_main_Dialog. print_control_identifiers( depth =None, filename=None) # 源码内部函数名链式赋值了,都能用,一样的 # print_ctrl_ids = dump_tree = print_control_identifiers depth:打印的深度,缺省时打印最大深度。
filename:将返回的标识存成文件(生成的文件与当前运行的脚本在同一个路径下)
eg:dlg. print_control_identifiers(filename =’a.txt’)

打印出来的文档树就是inspect中的控件树完全展开的样子,都是有层级的,和微信程序中的各个元素是一一对应的

三、控件查找定位 # 直接找窗口 win_main_Dialog = app.window(class_name= 'WeChatMainWndForPC' ) # 主窗口下的某个窗口,不管层级的找 chat_list = win_main_Dialog.child_window(control_type= 'List' , title= '会话' ) first = chat_list.items()[ 0 ] # 第一个聊天项 列表支持items(),支持循环,支持索引 chat_list.scroll( direction = 'down' , amount= 'page' ) # 向下滚动一页 # 详情页修改备注操作 parent()和children()都是只往上或往下查找一个层级,所有满足的放进列表 details_page = win_main_Dialog.child_window(class_name= 'ContactProfileWnd' ) # 窗口下的某个窗口 we_id = details_page.child_window(title= "微信号:" , control_type= "Text" ).parent().children()[ 1 ].window_text() # 窗口的爸爸的第二个儿子的文字 alia = details_page.child_window(title= "微信号:" , control_type= "Text" ).parent().parent().children()[ 0 ].children()[ 0 ].window_text() edit_btn = details_page.child_window(title= "备 注" , control_type= "Text" ).parent().children()[ 1 ] edit_btn.click_input() btn_modify_name_edit = edit_btn # 先ctrl+a选中所有然后再type_keys替换 btn_modify_name_edit.type_keys('^a').type_keys('备注名字', with_spaces = True ) # descendants查找所有后代中满足的,不管层级,所有满足的放进列表 btn_return = win_main_Dialog.child_window(control_type= 'ToolBar' ).parent().descendants(control_type= 'Button' ) btn_return [0] .click_input() title = "微信团队" # 对应inspect界面的Name,打印出来也会显示 class_name = 'WeChatLoginWndForPC' # 对应ClassName control_type = "Window" # 对应LocalizedControlType的英文版,打印出来后也会显示 control_type = "Text" control_type = "Button" control_type = "List" control_type = "ListItem" control_type = 'MenuItem' control_type = 'ToolBar' auto_id = 'FileTypeControlHost' 控件常见特征

四、控件自带的的方法 1. 点击和输入 # 左点击,可以点进源码,还有double_click_input,right_click_input等 edit_btn.click_input() # 先ctrl + a选中所有然后再type_keys替换,和我们选中然后修改一样的 edit_btn.type_keys( '^a' ).type_keys( '备注名字' , with_spaces = True ) SHIFT + CTRL ^ ALT % 空格键 {SPACE} BACKSPACE {BACKSPACE}、{BS} or {BKSP} BREAK {BREAK} CAPS LOCK {CAPSLOCK} DEL or DELETE { DELETE } or {DEL} DOWN ARROW {DOWN} END { END } ENTER {ENTER} or ~ ESC {ESC} HELP {HELP} HOME {HOME} INS or INSERT { INSERT } or {INS} LEFT ARROW { LEFT } NUM LOCK {NUMLOCK} PAGE DOWN {PGDN} PAGE UP {PGUP} PRINT SCREEN {PRTSC} RIGHT ARROW { RIGHT } SCROLL LOCK {SCROLLLOCK} TAB {TAB} UP ARROW {UP} + { ADD } - {SUBTRACT} * {MULTIPLY} / {DIVIDE} 常用快捷键

2.对控件截图并保存 ctrl_qrcode = self.win_login.child_window(title= '二维码' , control_type= 'Image' ) if ctrl_qrcode.exists(): ctrl_qrcode.capture_as_image().save(img_path) 3.窗口的等待 窗口加载需要时间,我们又不能一直sleep就需要等待,等待窗口出现或者等待窗口关闭:

save_dialog.wait('ready',timeout=2) save_dialog.close() save_dialog.wait_not('visible') # 'exists' :窗口是有效的句柄 # 'visible' :窗口未隐藏,常用 # 'enabled' :未禁用窗口 # 'ready' :窗口可见并启用,常用 # 'active' :窗口处于活动状态 # 顶层窗口 dlg = app.top_window() # 点方法取值 print(dlg.class_name()) #'WeChatMainWndForPC' chat_list.scroll( direction = 'up' , amount= 'page' ) 五、鼠标操作 from pywinauto import mouse 常见操作:

# 移动鼠标 mouse.move( coords =(x, y)) # 指定位置,鼠标左击 mouse.click( button = 'left' , coords=( 40 , 40 )) # 鼠标双击 mouse.double_click( button = 'left' , coords=( 140 , 40 )) # 将属性移动到(140,40)坐标处按下 mouse.press( button = 'left' , coords=( 140 , 40 )) # 将鼠标移动到(300,40)坐标处释放, mouse.release( button = 'left' , coords=( 300 , 40 )) # 右键单击指定坐标 mouse.right_click( coords =( 400 , 400 )) # 鼠标中键单击指定坐标(很少用的到) mouse.wheel_click( coords =( 400 , 400 )) # 滚动鼠标 wheel_dist指定鼠标滚轮滑动,正数往上,负数往下。 mouse.scroll( coords =( 1200 , 300 ),wheel_dist=- 3 ) # 以控件中心为起点,滚动 def mouse_scroll(control, distance): rect = control.rectangle() cx = int((rect.left+rect.right)/ 2 ) cy = int((rect.top + rect.bottom)/ 2 ) mouse.scroll( coords =(cx, cy), wheel_dist=distance) mouse_scroll( control =win_main_Dialog.child_window(control_type= 'List' , title= '联系人' ), distance=- 5 ) 六、键盘操作 和控件自己的type_keys方法效果一样,但是更快,那个是从前到后啪啪啪的输入,这个是一下就出来了那种

在发送文件和图片的时候可以使用键盘模块,复制粘贴,比啪啪啪输入路径再发送速度快多了

import keyboard import io for line in io .StringIO (msg): keyboard. write (line. strip ()) # keyboard. send ( 'ctrl+enter' ) keyboard. write (chat_name) keyboard. send ( 'enter' ) keyboard. send ( 'ctrl+v' )