您现在的位置是:首页 > 技术教程 正文

python进行windows系统UI自动化之【pyautoit】

admin 阅读: 2024-03-22
后台-插件-广告管理-内容页头部广告(手机)

python进行windows系统UI自动化之【pyautoit】

    • 一、AutoIT中文手册
      • 1.1、安装AutoIt
      • 1.2、使用Auto Window Info
    • 二、python引用
      • 2.1、安装
      • 2.2、引用
      • 2.3、使用
        • 2.3.1、窗口操作
        • 2.3.2、控件操作
        • 2.3.3、进程操作
        • 2.3.4、鼠标操作
        • 2.3.5、键盘操作
          • 2.3.5.1、Send 是非常有用的一个函数/命令,因为我们可用它来对窗口进行操作而无需使用鼠标。
            • 2.3.5.1.1、例如,先打开 文件夹选项窗口(位于控制面板),然后请尝试执行下面这些语句:
            • 2.3.5.1.2、组合 Alt 键使用可访问菜单项,请打开记事本窗口然后尝试执行下面这些语句:
            • 2.3.5.1.3、如果您对快捷键(Alt+F4、PrintScreen、Ctrl+C等等)的重要性还不太了解,请查看 Windows 的帮助信息(按下热键 Win+F1即可)以获得关于快捷键的完整列表。
    • 三、易报错点
      • 3.1 等待页面激活
      • 3.2点击
      • 3.1 打开文件
      • 四、项目所需,所封装的接口demo
    • 五、遇到的坑
    • 六、WEB UI自动化将AutoIT与Selenium结合
    • 七、 Windows PC自动化将AutoIT与Airtest结合

其实,用python进行windows端UI自动化的库有很多,比如pywinauto等,本文介绍一个使用autoit3来实现的 pyautoit 库。

pyautoit 是一个用python写的基于AutoItX3.dll的接口库,用来进行windows窗口的一系列操作,也支持鼠标键盘的操作。

AutoIt现在最新版是V3版本,这是一个类似BASIC脚本语言的免费软件,用于Windows GUI中进行自动化操作。利用模拟键盘按键,鼠标移动,窗口和控件的组合来实现自动化任务,而这是其他语言不可能做到和无可靠方法实现的(例如VBScript和SendKeds)

一、AutoIT中文手册

https://www.autoitx.com/doc/

1.1、安装AutoIt

链接: AutoIt Downloads - AutoIt
下载下图的安装包
在这里插入图片描述
解压后运行后第一个界面直接NEXT

在这里插入图片描述

1.2、使用Auto Window Info

控件control定位
打开Auto Window Info(x64)或Auto Window Info(x86)
在这里插入图片描述
类似于浏览器的F12,使用Finder Tool获取窗口的title等信息
在这里插入图片描述

点击上访的图标,进行拖拉,到想访问的位置,注意下图两个红框中的数值,上面的框表示页面的标题和类,下面的框表示控件的类和序号(一般连起来使用)
在这里插入图片描述

二、python引用

2.1、安装

pip install pyautoit https://pypi.org/project/PyAutoIt/
  • 1
  • 2
  • 3

2.2、引用

import autoit # 注意:引用的模块名跟安装的模块名是不一样的
  • 1

2.3、使用

启动程序 autoit.run("notepad.exe") run(filename[,work_dir[,show_flag]]): 运行指定程序 filename参数:设置运行的程序的路径和名称 work_dir参数:设置工作路径。默认为windows系统文件夹(C:\Windows) show_flag参数:设置窗口显示的方式。默认为Properties.SW_SHOWNORMAL(窗口正常显示) 可选值: ○ Properties.SW_HIDE: 表示隐藏窗口 ○ Properties.SW_MAXIMIZE: 表示最大化窗口 ○ Properties.SW_MINIMIZE: 表示最小化窗口 run_wait(filename[,work_dir[,show_flag]]): 运行指定程序并暂停脚本执行,直到程序结束
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
2.3.1、窗口操作
autoit.win_wait_active(title="无标题- 记事本", timeout=10) # 等待窗口激活 autoit.win_exists("aaa") # 判断窗口是否存在 autoit.win_get_handle("无标题- 记事本") # 获取窗口句柄 autoit.win_activate("bbb") # 激活窗口 autoit.win_close("[CLASS:Notepad]") # 关闭窗口 此处,窗口标题的匹配模式也是可以自定义的,默认是1 -- 匹配开始部分,可以在脚本前面加上以下改为2--匹配子字符串: autoit.opt("WinTitleMatchMode", 2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
autoit.win_active(title): 检查指定标题的窗口是否为激活状态返回值: ○ 1表示窗口已激活 ○ 0表示窗口未激活 autoit.win_close(title): 关闭指定标题的窗口 autoit.win_exists(title): 检查指定标题的窗口是否存在返回值:○ 1表示窗口已存在○ 0表示窗口未存在 autoit.win_get_pos(title): 获取指定标题的窗口的位置和尺寸(left, top, right, bottom) 返回值:[x, y, width, height] autoit.win_get_process 获取指定窗口关联的进程ID(PID/-1) autoit.win_get_text 获取指定窗口中的文本(文本/0) autoit.win_kill(title): 强制关闭指定标题的窗口 autoit.win_move 移动指定的窗口或调整窗口的大小(PID/0) 参数(x, y, width, height) autoit.win_set_state 显示,隐藏,最小化,最大化或还原一个窗口 参数(flag 1= 显示2 = 最小化/隐藏3 = 最大化4 = 还原) autoit.win_waitwin_wait(title[, timeout]): 暂停脚本的执行直至指定窗口存在(出现)为止(1/0) 参数(timeout 单位为秒)在指定时间内等待指定标题的窗口打开 time_out参数:设置超时时间,单位为秒(s)。默认为0,表示一直等待 autoit.win_wait_active 暂停脚本的执行直至指定窗口被激活(成为活动状态)为止 参数(timeout 单位为秒) autoit.win_wait_close(title[,timeout]): 暂停脚本的执行直至所指定窗口不再存在为止 参数(timeout 单位为秒) autoit.win_wait_active(title[, timeout]):暂停脚本的执行直至指定窗口不是激活状态为止 参数(timeout 单位为秒)在指定时间内等待指定标题的窗口激活time_out参数与win_wait_active函数的timeout参数相同 autoit.control_click 向指定控件发送鼠标点击命令 参数(timeout control 控件)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
#脚本连接窗口方法 #1. 使用窗口句柄 auto_setup(__ file__.devices=["Windows:///133194"]) #其中133194就是窗口句柄 #窗口句柄是每个Windows窗口对象拥有的独一无二的32位无符号整数,而且每次打开窗口,句柄的数值都会变化 #2. 使用正则表达式 auto_setup(__file__. devices=["Windows://?title_re=xxx.*]) #大多数情况下,窗口的titIe比较不容易变化,所以我们可以写一个正则表达 #3. 连接桌面 auto_setup(__file__. devices=["Windows:///]) #如果不需要指定某个窗口应用,我们可以直接连接整个桌面来做自动化
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
2.3.2、控件操作
autoit.control_set_text("无标题", "Edit1", "12312313123") # 输入文字 autoit. control_click(title, control[,button[, clicks[, x[, y]]]]): 对控件进行点击 button参数:设置点击方式。默认为“left”,还可以设置为"right" or "middle" clicks参数:设置点击次数。默认为1次 x: 设置点击的水平位置。默认为center(中心) y: 设置点击的垂直位置。默认为center(中心) autoit.control_get_text(title="title", control="controlid") # 获取控件文本 autoit.control_command(title="title", control="controlid", command="command") autoit.control_list_view(title="title", control="controlid", command="command") autoit.control_tree_view(title="title", control="controlid", command="command")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
2.3.3、进程操作
autoit.process.process_wait(process="process", timeout=10) autoit.process.process_close("process") autoit.process.process_exists("process")
  • 1
  • 2
  • 3
2.3.4、鼠标操作
autoit.mouse_click(button='left', x=100, y=200, clicks=1, speed=-1) mouse_click([button[, x, y[, clicks[, speed]]]]): 点击鼠标 button参数:设置点击方式。 默认为“left”, 还可以设置为"right", "middle", "main", "menu", "primary", "secondary" x,y参数:鼠标移动的位置。不传参表示在鼠标当前位置点击 clicks: 设置鼠标点击次数 speed: 设置鼠标移动的速度。默认-1,速度范围为[1, 100]1最快,100最慢 autoit.mouse_move(x=200, y=300, speed=-1) mouse_move(x, y[, speed]) autoit.mouse_wheel(direction="down")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
2.3.5、键盘操作
autoit.send("12312412") autoit.send("+{F10}") # 发送shift+F10(右键效果) autoit.send("^a") # 发送ctrl+a
  • 1
  • 2
  • 3
  • 4
win切换窗口(键盘按下alt,操作tab键) 操作步骤如下: AutoITLibrary.send {ALT DOWN} AutoITLibrary.send {tab} AutoITLibrary.send {tab} AutoItLibrary.Send {ALT UP} 其它键盘操作,请参考: 键盘输入 [Arguments] ${keys} ${flag}=0 [Documentation] 模拟键盘输入,需要两个参数: ... 第一个参数: 需要输入的键盘按键 ... 第二个参数: 标记变量,可选值,默认为0, ... 0: 代表第一个参数${keys}中的!+^#代表特殊按键 ... 1: 代表第一个参数${keys}中的所有字符都是普通字符串 ... 举例: ... ^a^c^v!{F4} 代表:Ctrl+a Ctrl+c Ctrl+v Alt+F4 ... 关于特殊按键的说明: ... 如果${flag}为0,则: ... ! 代表ALT按键 ... + 代表SHIFT按键 ... ^ 代表CTRL按键 ... # 代表WIN按键 ... 比如:!+a 代表:ALT+SHIFT+a ... 其他特殊按键: ... ${flags}为0的时候,还支持下述特殊按键: ... 输入 最终的键盘按键 ... {!} ! ... {#} # ... {+} + ... {^} ^ ... {{} { ... {}} } ... {SPACE} SPACE ... {ENTER} ENTER key on the main keyboard ... {ALT} ALT ... {BACKSPACE} or {BS} BACKSPACE ... {DELETE} or {DEL} DELETE ... {UP} Cursor up ... {DOWN} Cursor down ... {LEFT} Cursor left ... {RIGHT} Cursor right ... {HOME} HOME ... {END} END ... {ESCAPE} or {ESC} ESCAPE ... {INSERT} or {INS} INS ... {PGUP} PageUp ... {PGDN} PageDown ... {F1} - {F12} Function keys ... {TAB} TAB ... {PRINTSCREEN} Print Screen key ... {LWIN} Left Windows key ... {RWIN} Right Windows key ... {NUMLOCK on} NUMLOCK (on/off/toggle) ... {CAPSLOCK off} CAPSLOCK (on/off/toggle) ... {SCROLLLOCK toggle} SCROLLLOCK (on/off/toggle) ... {BREAK} for Ctrl+Break processing ... {PAUSE} PAUSE ... {NUMPAD0} - {NUMPAD9} Numpad digits ... {NUMPADMULT} Numpad Multiply ... {NUMPADADD} Numpad Add ... {NUMPADSUB} Numpad Subtract ... {NUMPADDIV} Numpad Divide ... {NUMPADDOT} Numpad period ... {NUMPADENTER} Enter key on the numpad ... {APPSKEY} Windows App key ... {LALT} Left ALT key ... {RALT} Right ALT key ... {LCTRL} Left CTRL key ... {RCTRL} Right CTRL key ... {LSHIFT} Left Shift key ... {RSHIFT} Right Shift key ... {ALTDOWN} Holds the ALT key down until {ALTUP} is sent ... {SHIFTDOWN} Holds the SHIFT key down until {SHIFTUP} is sent ... {CTRLDOWN} Holds the CTRL key down until {CTRLUP} is sent ... {LWINDOWN} Holds the left Windows key down until {LWINUP} is sent ... {RWINDOWN} Holds the right Windows key down until {RWINUP} is sent ... {ASC nnnn} Send the ALT+nnnn key combination AutoItLibrary.Send ${keys} ${flag} 键盘输入Alt+F4 AutoItLibrary.Send !{F4} 键盘输入Ctrl+Space AutoItLibrary.Send ^{SPACE} 键盘输入Ctrl+a AutoItLibrary.Send ^a 键盘输入Ctrl+c AutoItLibrary.Send ^c 键盘输入Ctrl+v AutoItLibrary.Send ^v 键盘输入Ctrl+s AutoItLibrary.Send ^s 键盘输入Ctrl+p AutoItLibrary.Send ^p 键盘输入Ctrl+Home AutoItLibrary.Send ^{HOME} 键盘输入Ctrl+End AutoItLibrary.Send ^{END} 键盘输入Win+d 键盘输入 {LWINDOWN}d{LWINUP} 键盘输入Win+r 键盘输入 {LWINDOWN}r{LWINUP} AutoIt 可发送所有的 ASCII 码及扩展 ASCII 码字符(0-255),若要发送 UNICODE 编码的字符则必须使用“ASC”选项加上您要发送的字符代码(见下面的 {ASC})。 Send("#r");开始运行 Send("^!+{F6}") ;发送CTRL+ALT+F6组合键 如果要发送 ASCII 字符 A 则参考下例(相当于 ALT+065,按住ALT键并在数字键盘上顺序按下065) Send("{ASC 065}") (在使用两位数的 ASCII 码时必须在前面加一个 0,否则将使用 437号代码页) 如果要发送 UNICODE 字符则输入该字符代码,例如下例将发送一个中文字符 Send("{ASC 2709}") 可参考下例重复发送某按键: Send("{DEL 4}") ;连续4次按下 DEL 键 Send("{S 30}") ;发送30个字符“S” Send("+{TAB 4}) ;连续4次按下 SHIFT+TAB 如果要按住(保持按下状态)某个按键(通常用于游戏中) Send("{a down}") ;按住按键 A Send("{a up}") ;松开按键 A 如果要用变量来指定重复发送的次数,参考下例: $n = 4 Send("+{TAB " & $n & "}") 如果要用变量来指定要重复发送的 ASCII 字符(比如 A),参考下例: $x = Chr(65) Send("{" & $x & " 4}") 大多数笔记本电脑的键盘上都会有一个特殊的 Fn 键,此键无法被模拟。 注意,若把标志参数的值设为1则“按键”参数将被原样发送。如果某些文本是从变量里拷贝而来,而您又希望完全按原样发送这些文本的话,就应该使用这一设置。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
2.3.5.1、Send 是非常有用的一个函数/命令,因为我们可用它来对窗口进行操作而无需使用鼠标。
2.3.5.1.1、例如,先打开 文件夹选项窗口(位于控制面板),然后请尝试执行下面这些语句:
Send("{TAB}") 切换到(焦点切换)下一个控件(按钮、复选框等) Send("+{TAB}") 切换到上一个控件 Send("^{TAB}") 切换到下一个窗口标签 Send("^+{TAB}") 切换到上一个窗口标签 Send("{SPACE}") 可用来切换复选框的选中状态或点击某个按钮 Send("{+}") 通常用来选中某个复选框(如果它“确实是”复选框的话) Send("{-}") 通常用来取消选中某个复选框 Send("{NumPadMult}") 完全展开 SysTreeView32 控件内显示的文件夹
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
2.3.5.1.2、组合 Alt 键使用可访问菜单项,请打开记事本窗口然后尝试执行下面这些语句:
Send("!f") 发送 Alt+f,这是打开记事本的文件菜单的快捷键,您还可以试试其它的! Send("{DOWN}") 移动焦点到下一个菜单项 Send("{UP}") 移动焦点到上一个菜单项 Send("{LEFT}") 切换到左边的菜单或收缩子菜单 Send("{RIGHT}") 切换到右边的菜单或展开子菜单
  • 1
  • 2
  • 3
  • 4
  • 5
2.3.5.1.3、如果您对快捷键(Alt+F4、PrintScreen、Ctrl+C等等)的重要性还不太了解,请查看 Windows 的帮助信息(按下热键 Win+F1即可)以获得关于快捷键的完整列表。
Send 命令(无标志参数) 键击结果 {!} ! {#} # {+} + {^} ^ {{} { {}} } {SPACE} 空格 {ENTER} 主键盘区的 回车键 {ALT} ALT {BACKSPACE} 或 {BS} 退格 {DELETE} 或 {DEL} 删除(DELETE) {UP} 向上箭头 {DOWN} 向下箭头 {LEFT} 向左箭头 {RIGHT} 向右箭头 {HOME} HOME {END} END {ESCAPE} 或 {ESC} ESC键 {INSERT} 或 {INS} INS(Insert) {PGUP} PGUP(PageUp) {PGDN} PGDN(PageDown) {F1} - {F12} 功能键 {TAB} TAB {PRINTSCREEN} PRINTSCREEN {LWIN} 左徽标键 {RWIN} 右徽标键 {NUMLOCK} NUMLOCK {CTRLBREAK} Ctrl+Break {PAUSE} PAUSE {CAPSLOCK} CAPSLOCK {NUMPAD0} - {NUMPAD9} 数字键盘上的 数字键 {NUMPADMULT} 数字键盘上的 乘号 {NUMPADADD} 数字键盘上的 加号 {NUMPADSUB} 数字键盘上的 减号 {NUMPADDIV} 数字键盘上的 除号 {NUMPADDOT} 数字键盘上的 点号 {NUMPADENTER} 数字键盘上的 回车键 {APPSKEY} Windows 应用程序键 {LALT} 左 ALT 键 {RALT} 右 ALT 键 {LCTRL} 左 CTRL 键 {RCTRL} 右 CTRL 键 {LSHIFT} 左 Shift 键 {RSHIFT} 右 Shift 键 {SLEEP} 系统休眠(SLEEP)键 {ALTDOWN} 按住 ALT 键直到发送 {ALTUP} 为止 {SHIFTDOWN} 按住 SHIFT 键直到发送 {SHIFTUP} 为止 {CTRLDOWN} 按住 CTRL 键直到发送 {CTRLUP} 为止 {LWINDOWN} 按住左徽标键直到发送 {LWINUP} 为止 {RWINDOWN} 按住右徽标键直到发送 {RWINUP} 为止 {ASC nnnn} 发送 ALT+nnnn 组合键 {BROWSER_BACK} 仅支持2000/XP:按下浏览器中的“后退”按钮 {BROWSER_FORWARD} 仅支持2000/XP:按下浏览器中的“前进”按钮 {BROWSER_REFRESH} 仅支持2000/XP:按下浏览器中的“刷新”按钮 {BROWSER_STOP} 仅支持2000/XP:按下浏览器中的“停止”按钮 {BROWSER_SEARCH} 仅支持2000/XP:按下浏览器中的“搜索”按钮 {BROWSER_FAVORITES} 仅支持2000/XP:按下浏览器中的“收藏夹”按钮 {BROWSER_HOME} 仅支持2000/XP:运行浏览器并转到主页 {VOLUME_MUTE} 仅支持2000/XP:切换系统静音状态 {VOLUME_DOWN} 仅支持2000/XP:减小系统音量 {VOLUME_UP} 仅支持2000/XP:增大系统音量 {MEDIA_NEXT} 仅支持2000/XP:在播放器中选择播放下一个轨道(影音媒体) {MEDIA_PREV} 仅支持2000/XP:在播放器中选择播放上一个轨道 {MEDIA_STOP} 仅支持2000/XP:使播放器停止播放 {MEDIA_PLAY_PAUSE} 仅支持2000/XP:使播放器播放/暂停 {LAUNCH_MAIL} 仅支持2000/XP:运行邮件客户端程序 {LAUNCH_MEDIA} 仅支持2000/XP:运行播放器(Media player) {LAUNCH_APP1} 仅支持2000/XP:运行用户程序1(我的电脑) {LAUNCH_APP2} 仅支持2000/XP:运行用户程序2(计算器)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

三、易报错点

3.1 等待页面激活

autoit.win_wait_active("[CLASS:Notepad]", 3)#等待3秒 #常用于切换页面后,最好加上,不然容易报错window/control cannot find
  • 1
  • 2

3.2点击

#用标题或者类名表示当前页面,一般两个方法通用 #如果报错window/control cannot find,可以尝试换一种方法表示 autoit.control_click("[CLASS:Notepad]", "Button2") autoit.control_click("*无标题 - 记事本", "Button2")
  • 1
  • 2
  • 3
  • 4

3.1 打开文件

一般以我们平时操作,会从下图上方的地址栏进行操作,这里注意可以直接从下方的文件名处,输入对应的绝对地址,如:F:\程序设计书籍\《啊哈!算法》.pdf
在这里插入图片描述

autoit.control_set_text("Open File", "Edit1",file_path) # 输入文件地址
  • 1

四、项目所需,所封装的接口demo

import autoit class MyPyAutoIt(object): @staticmethod def open_exe(title, exe_path, timeout=30): ''' 打开软件并等待加载完成,窗口最大化 :return: ''' try: autoit.run(exe_path) autoit.win_wait_active(title, timeout) autoit.win_set_state(title, flag=autoit.autoit.Properties.SW_MAXIMIZE) except Exception as e: print(e) print('软件打开失败') exit(1) @staticmethod def send_keys(title, control, text): ''' 指定输入框输入文本 :param title: 主窗口标题 :param control: 对应的控件的ClassnameNN :param text: 要输入的文本 :return: ''' autoit.control_click(title, control) time.sleep(0.1) # 复制 pyperclip.copy(text) # ctrl + v autoit.send('{CTRLDOWN}') autoit.send('{v down}') autoit.send('{v up}') autoit.send('{CTRLUP}') @staticmethod def control_click(title, control): ''' 点击该打开软件的某个控件 :param title: 主窗口标题 :param control: 对应的控件的ClassnameNN :return: 返回点击控件后的界面的text control对 ''' autoit.control_click(title, control) if title == 'xxxxxx': time.sleep(2) return MyPyAutoIt.get_dic(title) @staticmethod def control_click_no_wait(title, control): ''' 点击该打开软件的某个控件 :param title: 主窗口标题 :param control: 对应的控件的ClassnameNN :return: 返回点击控件后的界面的text control对 ''' autoit.control_click(title, control) @staticmethod def close_notice_window(title='提示', control=None, timeout=10): ''' 点击该打开软件的提示窗口的某个控件 :param title: 提示窗口标题 :param control: 对应的控件的ClassnameNN :param timeout: 超时时间 :return: ''' def close_inform(): autoit.send('{TAB}') autoit.send('{TAB}') autoit.send('{SPACE}') autoit.send('{TAB}') autoit.send('{SPACE}') autoit.send('{TAB}') autoit.send('{TAB}') autoit.send('{SPACE}') autoit.send('{TAB}') autoit.send('{SPACE}') autoit.send('{SPACE}') autoit.send('{SPACE}') try: if title == '提示': autoit.win_wait_active(title, timeout) autoit.control_click(title, control) elif title == '告知书': autoit.win_wait(title, timeout) autoit.mouse_click(x=800, y=400) # 点击告知书提示框使其被选中 close_inform() autoit.send('{SPACE}') autoit.send('{SPACE}') except Exception as e: print('{}窗口关闭失败, msg : {}'.format(title, str(e))) @staticmethod def ca_login(title='FormAccountPassword', psw_input_control=None, login_control=None, timeout=10): ''' 增值税 一般纳税人 进入该表时要用CA密码验证 :param title: :param psw_input_control: :param login_control: :param timeout: :return: ''' autoit.win_wait_active(title, timeout) MyPyAutoIt.send_keys(title, psw_input_control, 'xxxxxx') MyPyAutoIt.control_click(title, login_control) @staticmethod def get_username(title, username_list): ''' 获得账号名和对应的control组成的dict :param title: :param username_list: 账号(公司全称)构成的list :return:dict, key为公司全称, value为对应的control ''' dic = {} for key, value in MyPyAutoIt.get_dic(title).items(): if key in username_list: dic[key] = value return dic @staticmethod def get_dic(title): ''' :param title: :param control :要获取的控件的Class :return: 由text和对应的control组成的字典, key:text, value:control ''' static_control = 'WindowsForms10.STATIC.app.0.33c0d9d' button_control = 'WindowsForms10.BUTTON.app.0.33c0d9d' edit_control = 'WindowsForms10.EDIT.app.0.33c0d9d' def get_d(control_str, n=500): d = {} for s in (control_str + str(i) for i in range(1, n)): try: key = autoit.control_get_text(title, s) if key == '': continue elif key in d.keys(): if isinstance(d[key], list): d[key] = d[key].append(s) else: d[key] = [d[key], s] else: d[key] = s except autoit.autoit.AutoItError: continue return d return dict(get_d(static_control), **get_d(button_control), **get_d(edit_control)) @staticmethod def get_text_control(title): ''' 获取该界面中的text和其对应的control :param title: 窗口标题 :return: 由text和对应的control组成的字典, key:text, value:control ''' return MyPyAutoIt.get_dic(title) @staticmethod def switch_account(title, username, username_list): ''' 切换账号 :param title: 主窗口标题 :param username_list: 公司全称列表 :param username: 要切换的公司全称 :return: ''' dic = MyPyAutoIt.get_username(title, username_list) return MyPyAutoIt.control_click(title, dic[username]) @staticmethod def get_check_result(title, timeout=2): ''' 获取审核结果 :param title: :param timeout: :return:返回审核结果 ''' autoit.win_wait_active(title, timeout) return autoit.win_get_text(title) @staticmethod def exit_table(title, control='WindowsForms10.BUTTON.app.0.33c0d9d1', timeout=5): ''' 返回上一级,返回税表的上一级(提示要保存表格数据时,默认不保存) :param title: :param control: :param timeout: :return: ''' MyPyAutoIt.control_click(title, control) try: autoit.win_wait_active('提示', timeout) MyPyAutoIt.control_click('提示', 'Button2') except autoit.autoit.AutoItError: pass @staticmethod def get_text_by_control(title, control): ''' 根据给定的control 获取对应的text :param title: :param control: :return: ctrl对应的text ''' return autoit.control_get_text(title, control) @staticmethod def screen_capture(title, control, text=''): ''' 对相应的控件截图 :param title: :param control: :param text: :return: ''' left, top, right, bottom = autoit.control_get_pos(title, control, text) img = ImageGrab.grab((left, top, right, bottom)) img.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
import autoit class MouseControl(object): ''' AutoIt鼠标相关操作 ''' def __init__(self): ''' Constructor ''' def click(self, title, text, x, y, button="main", clicks=1): ''' :description 执行鼠标点击操作 ''' pos = autoit.win_get_pos(title, text=text) autoit.mouse_click(button, x + pos[0], y + pos[1], clicks=clicks) def move(self, title, text, x, y): ''' :description 移动鼠标指针 ''' pos = autoit.win_get_pos(title, text=text) autoit.mouse_move(x + pos[0], y + pos[1]) def drag(self, title, text, x1, y1, x2, y2): ''' :description 执行鼠标拖拽操作 ''' pos = autoit.win_get_pos(title, text=text) autoit.mouse_click_drag(x1 + pos[0], y1 + pos[1], x2 + pos[0], y2 + pos[1]) def wheel(self, direction="up"): ''' :description 产生向上或向下滚动鼠标滚轮事件.仅支持NT/2000/XP及更高. ''' autoit.mouse_wheel(direction) mouseControl.py
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
import autoit class ProcessControl(object): ''' AutoIt进程相关操作 ''' def __init__(self, processName): ''' Constructor ''' self.processName = processName def close(self): ''' :description 终止某个进程 :return 1:成功; 0:失败. ''' return autoit.process_close(self.processName) def exists(self): ''' :description 检查指定进程是否存在 :return PID:成功; 0:进程不存在. ''' return autoit.process_exists(self.processName) processControl
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
import autoit class WinControl(object): ''' AutoIt窗口相关操作 ''' def __init__(self, title, text=''): ''' Constructor ''' self.title = title self.text = text def activate(self): ''' :description 激活指定的窗口(设置焦点到该窗口,使其成为活动窗口). :return PID:窗口存在; 0:窗口不存在. ''' return autoit.win_activate(self.title, text=self.text) def close(self): ''' :description 关闭指定窗口. :return 1:成功; 0:窗口不存在. ''' return autoit.win_close(self.title, text=self.text) def exists(self): ''' :description 检查指定的窗口是否存在. :return 1:窗口存在; 0:窗口不存在. ''' return autoit.win_exists(self.title, text=self.text) def getPos(self): ''' :description 获取指定窗口的坐标位置和大小等属性. :return Returns left, top, right, bottom (x1,y1,x2,y2) ''' return autoit.win_get_pos(self.title, text=self.text) def getProcess(self): ''' :description 获取指定窗口关联的进程ID(PID). :return PID:成功, -1:失败. ''' return autoit.win_get_process(self.title, text=self.text) def getText(self, buf_size=256): ''' :description 获取指定窗口中的文本. :return 指定窗口里包含的文本:成功; 0:失败(没有匹配的窗口). ''' return autoit.win_get_text(self.title, buf_size, text=self.text) def kill(self): ''' :description 强行关闭指定窗口. :return 1:无论成功失败. ''' return autoit.win_kill(self.title, text=self.text) def move(self, x, y, width, height): ''' :description 移动指定的窗口或调整窗口的大小. :return PID:成功, 0:失败(窗口不存在). ''' return autoit.win_move(self.title, x, y, width, height, text=self.text) def setState(self, flag): ''' :description 显示,隐藏,最小化,最大化或还原一个窗口. :param flag: The "show" flag of the executed program: = 显示 = 最小化/隐藏 = 最大化 = 还原 :return 1:成功, 0:失败(窗口不存在). ''' return autoit.win_set_state(self.title, flag, text=self.text) def wait(self, timeout=5): ''' :description 暂停脚本的执行直至指定窗口存在(出现)为止. timeout 单位为秒. :return PID:成功, 0:失败(超时). ''' return autoit.win_wait(self.title, timeout, text=self.text) def waitActive(self, timeout=5): ''' :description 暂停脚本的执行直至指定窗口被激活(成为活动状态)为止. timeout 单位为秒. :return PID:成功, 0:失败(超时). ''' return autoit.win_wait_active(self.title, timeout, text=self.text) def waitClose(self, timeout=5): ''' :description 暂停脚本的执行直至所指定窗口不再存在为止. timeout 单位为秒. :return 1:成功, 0:失败(超时). ''' return autoit.win_wait_close(self.title, timeout, text=self.text) def waitNotActive(self, timeout=5): ''' :description 暂停脚本的执行直至指定窗口不是激活状态为止. timeout 单位为秒. :return 1:成功, 0:失败(超时). ''' return autoit.win_wait_not_active(self.title, timeout, text=self.text) def controlClick(self, control, button="main", clicks=1): ''' :description 向指定控件发送鼠标点击命令. ''' autoit.control_click(self.title, control, text=self.text, button=button, clicks=clicks) def controlCommand(self, control, command, extra="", buf_size=256): ''' :description 向指定控件发送命令. :param command, extra: :return "IsVisible", "" 1:可见; 0:不可见 "IsEnabled", "" 1:可用; 0:禁用 "ShowDropDown", "" 弹出/下拉 组合框(ComboBox)的列表. "HideDropDown", "" 收回/隐藏 组合框(ComboBox)的列表. "AddString", "string" 在 ListBox 或 ComboBox 的编辑框后面附加指定字符串. "DelString", 出现次序 删除在 ListBox 或 ComboBox 的编辑框中指定的字符串(从0开始). "FindString", "string" 返回在 ListBox 或 ComboBox 的编辑框中与指定字符串匹配项目的出现次序(从0开始). "SetCurrentSelection", 出现次序 通过指定出现次序(从0开始)把 ListBox 或 ComboBox 的当前选择项设为指定的项目. "SelectString","string" 通过指定字符串把 ListBox 或 ComboBox 的当前选择项设为匹配字符串的项目. "IsChecked", "" 若目标按钮(复选框/单选框)被选中则返回值为1,否则为0. "Check", "" 使目标按钮(复选框/单选框)变为选中状态. "UnCheck", "" 使目标按钮(复选框/单选框)变为非选中状态. "GetCurrentLine", "" 返回在目标编辑框中插入符(caret,光标)的所在行号. "GetCurrentCol", "" 返回在目标编辑框中插入符(caret,光标)的所在列号. "GetCurrentSelection", "" 返回 ListBox 或 ComboBox 控件当前选中的项目名. "GetLineCount", "" 返回目标编辑框中的总行数. "GetLine", 行号 返回目标编辑框中指定行的文本内容. "GetSelected", "" 返回目标编辑框中的(用户用鼠标或其它方式)选定的文本. "EditPaste", 'string' 在目标编辑框中插入符(caret)所在位置后插入指定字符串. "CurrentTab", "" 返回在 SysTabControl32 控件中当前显示的标签编号(从1开始). "TabRight", "" 使 SysTabControl32 控件切换到(右边的)下一个标签. "TabLeft", "" 使 SysTabControl32 控件切换到(左边的)下一个标签. "SendCommandID", 命令 ID 模拟 WM_COMMAND 消息. 通常用于 ToolbarWindow32 控件 - 使用Au3Info的工具栏标签得到命令ID. ''' return autoit.control_command(self.title, control, command, buf_size, text=self.text, extra=extra) def controlListView(self, control, command, extra1, extra2="", buf_size=256): ''' :description 向指定的 ListView32 控件发送命令. :param command, extra1, extra2: :return "DeSelect", 从[, 到] 取消选定从"从"开始直到"到"的一个或多个项目. "FindItem", "搜索字符串" [, 子项目] 返回与给定字符串匹配的项目的位置.若未找到指定字符串则返回值为 -1. "GetItemCount" 返回列表中项目的数量. "GetSelected" [, 选项] 返回当前选中项目的位置.若 选项=0(默认)则只返回选中的第一个项目;若 选项=1 则返回由竖线"|"作为分隔符的所有选中项目,例如:"0|3|4|10".若没有选中任何项目则返回一个空字符串"". "GetSelectedCount" 返回选中项目的数量. "GetSubItemCount" 返回子项目的数量. "GetText", 项目, 子项目 返回指定项目/子项目的文本. "IsSelected", 项目 若指定项目被选中则返回值为1,否则返回值为0. "Select", 从[, 到] 选中一个或多个项目(请参考第一个命令). "SelectAll" 选中所有项目. "SelectClear" 取消所有项目的选中状态. "SelectInvert" 切换当前的选中状态. "ViewChange", "视图" 切换当前的视图.可用的视图包括"list"(列表),"details"(详细信息),"smallicons"(小图标),"largeicons"(大图标). ''' return autoit.control_list_view(self.title, control, command, buf_size, text=self.text, extra1=extra1, extra2=extra2) def controlDisable(self, control): ''' :description 禁用或使某控件变成灰色不可用状态. :return 1:成功; 0:失败. ''' return autoit.control_disable(self.title, control, text=self.text) def controlEnable(self, control): ''' :description 使灰色按钮/控件变为"可用"状态. :return 1:成功; 0:失败. ''' return autoit.control_enable(self.title, control, text=self.text) def controlFocus(self, control): ''' :description 设置输入焦点到指定窗口的某个控件上. :return 1:成功; 0:失败. ''' return autoit.control_focus(self.title, control, text=self.text) def controlGetText(self, control): ''' :description 获取指定控件上的文本. :return 文本内容:成功; 空:失败. ''' return autoit.control_get_text(self.title, control, text=self.text) def controlSend(self, control, send_text, mode=0 ): ''' :description 向指定的控件发送字符串. :param mode: 0:按特殊字符含义发送(默认); 1:原样发送. :return 1:成功; 0:失败(窗口/控件未找到). ''' return autoit.control_send(self.title, control, send_text, mode, text=self.text) def controlSetText(self, control, control_text): ''' :description 修改指定控件的文本. :return 1:成功; 0:失败(窗口/控件未找到). ''' return autoit.control_set_text(self.title, control, control_text, text=self.text) def controlTreeView(self, control, command, extra, buf_size=256): ''' :description 发送一个命令到 TreeView32 控件.(子节点不好用*) :param command, extra :return "Check", "项目" 选中一个项目 (如果项目支持选中,这里指项目带有选择框). "Collapse", "项目" 折叠一个项目节点,使它隐藏它的子项目. "Exists", "项目" *都返回1* 如果项目存在返回 1,否则返回 0. "Expand", "项目" 展开一个项目节点,使它显示它的子项目. "GetItemCount", "项目" 返回所选项目的子项目数量. "GetSelected" [, 使用索引] 返回当前所选项目的文本参考信息(如果使用索引设置为1将会返回所选项目索引位置). "GetText", "项目" 返回项目文本. "IsChecked" 返回项目选中状态. 1:被选中, 0:未被选中, -1:没要选择框. "Select", "项目" 选择一个项目. "Uncheck", "项目" 取消项目选中状态 (如果项目支持选中,这里指项目带有选择框). ''' return autoit.control_tree_view(self.title, control, command, text=self.text, buf_size=buf_size, extra=extra) def statusbarGetText(self, part=1, buf_size=256): ''' :description 获取标准状态栏控件的文本. :return 文本内容:成功; 空字符串:失败(无法读取文本). ''' return autoit.statusbar_get_text(self.title, self.text, part, buf_size) winControl
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239

五、遇到的坑

  1. 在等待窗口出现时,比较了try和while方法,觉得还是while方法比较方面和好用,尤其是你将等待出现的窗口可能有好几种不同的窗口时,用while+if就很方便。
def isclientupdate(): '''判断包是否需要升级''' w_clientupdate = winControl.WinControl(title_update) w_clientupdate_choice = winControl.WinControl(title_choice) flag = True count = 0 while flag: if w_clientupdate.exists(): clientupdate() flag = False elif w_clientupdate_choice.exists(): w_clientupdate_choice.controlClick('Button2') clientupdate() flag = False else: time.sleep(1) count += 1 if count == 5: clientlogin() flag = False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

六、WEB UI自动化将AutoIT与Selenium结合

# Writer:Taka from selenium import webdriver from time import sleep from selenium.webdriver.common.action_chains import ActionChains import os from tools.Hightlightelement import heighLightElement driver = webdriver.Chrome() driver.get("https://sahitest.com/demo/php/fileUpload.htm") sleep(2) ele = driver.find_element_by_id('file') heighLightElement(driver,ele) ActionChains(driver).click(ele).perform() sleep(2) os.system(r'D:\PYFILE\PycharmProjects\UI_automation\tools\test.exe') sleep(3) driver.quit()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

七、 Windows PC自动化将AutoIT与Airtest结合

''后续介绍

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索