首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构之ElementNotFoundError(详细教程)

PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构之ElementNotFoundError(详细教程)

原创
作者头像
北京-宏哥
发布于 2025-01-23 14:30:50
发布于 2025-01-23 14:30:50
43400
举报
运行总次数:0

1.简介

其实前边的文章宏哥已经在控制台打印过控件菜单树结构,只是没有将其保存到文件中。只需要一个方法即可。在pywinauto中可以使用 print_control_identifiers() 方法打印控件菜单树结构,这对我们查找控件非常方便。宏哥今天将其单独拎出来是因为Windows10系统和Windows11系统会有一个坑,而且宏哥掉里边了,查了好多资料都没有找到解决办法,最后还好通过自己各种尝试将坑填平,成功爬出来了。其实前边已经遇到了打开记事本最后替换成了notepad++。今天跟随宏哥一步步入坑,然后再一步步填坑,最后成功解决。

2.控件操作

程序窗口中的内容,把它称之为控件,我们要对这个窗口的内容进行操作,就需要选择到对应的控件,获取所有控件我们可以通过print_control_identifiers()这个方法,来获取这个窗口下的直接子控件。因此我们为了清楚可以将控件的菜单结构树打印出来,一目了然。

3.起因

宏哥的台式电脑是Windows10系统的,但是宏哥的笔记本却是Windows11系统的。宏哥在学习和演示打印控件菜单树结构的时候,宏哥首先是在台式电脑(Win10系统)上操作和演示(打印记事本控件结构树)的,但是文章就写了一半,没有写完。这时候刚好由于出差宏哥只能被迫背上笔记本电脑(Win11系统),于是宏哥想要完成剩下的文章就继续将Windows10系统运行成功的代码,直接在Windows11系统上拷贝运行演示操作,结果报错了。。。。运行失败了,一时很懵,不知道如何解决,查了好多资料发现好多人都遇到同样的问题,但是就是没有给出解决办法,有的是提一句如何如何做,宏哥都一一试过了,都不行。就是这样就调入坑中了,要是一直在Windows10系统上操作演示或许就不会有这一篇文章,这一回事了。一切都是命啊,万般不由人,但是臣妾做到了。由于宏哥写文章的时候,手头还是没有Windows10,就网上找了一台免费微软提供类似win10系统,然后简单的搭建了一个环境给小伙伴或者童鞋们进行演示,有兴趣的自己可以试一下:实验 - 使用 Microsoft Office 集成 - Training | Microsoft Learn

4.Windows10系统

4.1代码设计

4.2参考代码

代码语言:javascript
代码运行次数:0
运行
复制
# -*- coding:utf-8 -*-

# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2025-02-12
@author: 北京-宏哥
北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!)
Project: PC端自动化测试实战教程-6-pywinauto打印和保存控件菜单树结构(详细教程)
'''

# 3.导入模块
from pywinauto import Application
import time

# 通过窗口打开
app = Application('uia').start("notepad.exe")
win = app['Untitled - Notepad']
print(win)
print(app.process)
win.print_control_identifiers()

4.3运行代码

1.运行代码,右键Run'Test',就可以看到控制台输出,如下图所示:

2.运行代码后电脑端的动作(启动记事本)。如下图所示:

5.Windows11系统

1.宏哥出差了,然后想也没想就将上边在Windows10系统运行成功的代码拷贝到笔记本Windows11系统上的Pycharm中进行运行,结果报错了:pywinauto.findwindows.ElementNotFoundError: {'best_match': 'Untitled - Notepad', 'backend': 'uia', 'process': 31680}

5.1运行代码

1.运行代码,右键Run'Test',就可以看到控制台输出,如下图所示:

2.运行代码后电脑端的动作(启动记事本)。如下图所示:

5.2报错分析

1.宏哥眼睁睁地看记事本启动了,报错却告诉我找不到元素。这不是前后矛盾啊。因为代码中宏哥打印了启动记事本进程号是:28192,如下图所示:

2.然后宏哥查看笔记本电脑的任务管理器的记事本的进程号是:24196 ,如下图所示:

 3.宏哥再次用工具查看,进程号是:24196,如下图所示:

总结:工具查看和任务管理器查看的进程号(24196)相同,但是代码运行启动的进程号(28192)与它们的进程号(24196)不一样,所有才会报错找不到元素,这就可以说通了为啥报这个错。

6.填坑实践

6.1加等待

1.开始填坑,查了好多资料网上说,可能是由于代码运行的快,而PC端程序启动慢导致的,需要加等待,换句话说:应用程序可能需要一段时间才能完全初始化其窗口和UI元素。即便start()方法在内部尝试连接,但如果UI还未完全加载,后续立即进行窗口或控件查找可能失败。于是宏哥就加了等待的代码。

6.1.1代码设计

6.1.2参考代码

代码语言:javascript
代码运行次数:0
运行
复制
# -*- coding:utf-8 -*-

# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2025-02-12
@author: 北京-宏哥
北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!)
Project: PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构(详细教程)
'''

# 3.导入模块
from pywinauto import Application
import time

# 通过窗口打开
app = Application('uia').start("notepad.exe")
time.sleep(3)
win = app['无标题 - Notepad']
print(win)
print(app.process)
win.print_control_identifiers()

6.1.3运行代码

1.运行代码,右键Run'Test',就可以看到控制台输出,如下图所示:

2.运行代码后电脑端的动作(启动记事本)。如下图所示:

6.2改路径

1.从上边看到我们失败了,然后宏哥继续查资料,又发现说是将start括号里写成路径的格式就可以。结果仍然是报一样的错误。如下图所示:

6.2.1参考代码

代码语言:javascript
代码运行次数:0
运行
复制
# -*- coding:utf-8 -*-

# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2025-02-12
@author: 北京-宏哥
北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!)
Project: PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构(详细教程)
'''

# 3.导入模块
from pywinauto import Application
import time

# 通过窗口打开
app = Application('uia').start("C:/Windows/notepad.exe")
time.sleep(3)
win = app['无标题 - Notepad']
print(win)
print(app.process)
win.print_control_identifiers()

6.3 connect()

手动调用connect()给予额外的时间缓冲,可能恰好让UI准备就绪。结果仍然是报一样的错误。

6.3.1参考代码

代码语言:javascript
代码运行次数:0
运行
复制
# -*- coding:utf-8 -*-

# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2025-02-12
@author: 北京-宏哥
北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!)
Project: PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构(详细教程)
'''

# 3.导入模块
from pywinauto import Application
import time

# 通过窗口打开
app = Application('uia').start("notepad.exe")

app = Application('uia').connect(class_name="Notepad")
win = app['无标题 - Notepad']
print(win)
print(app.process)
win.print_control_identifiers()

6.4 connect()和visible_only参数

手动调用connect()给予额外的时间缓冲,然后加上visible_only参数,这是宏哥自己想到的,因为在上边的报错中宏哥看到了visible_only参数,于是宏哥决定加上参数试一下。如下图所示:

6.4.1代码设计

6.4.2参考代码

代码语言:javascript
代码运行次数:0
运行
复制
# -*- coding:utf-8 -*-

# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2025-02-12
@author: 北京-宏哥
北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!)
Project: PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构(详细教程)
'''

# 3.导入模块
from pywinauto import Application
import time

# 通过窗口打开
app = Application('uia').start("notepad.exe")

app = Application('uia').connect(class_name="Notepad",visible_only=False)
win = app['无标题 - Notepad']
print(win)
print(app.process)
win.print_control_identifiers()

6.4.3运行代码

1.运行代码,右键Run'Test',就可以看到控制台输出,如下图所示:

2.运行代码后电脑端的动作(启动记事本)。如下图所示:

6.5 connect()和等待

这个也是宏哥在一次偶然运行代码中发现的,因为宏哥忘记将等待的代码段注释掉,结果运行代码成功!哈哈~~,坑一下子就这样跳出来了,要问宏哥是什么原因,宏哥也是一脸懵,一头问号,反正不管怎么说,问题就这样得到解决了。

6.5.1代码设计

6.5.2参考代码

代码语言:javascript
代码运行次数:0
运行
复制
# -*- coding:utf-8 -*-

# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2025-02-12
@author: 北京-宏哥
北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!)
Project: PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构(详细教程)
'''

# 3.导入模块
from pywinauto import Application
import time

# 通过窗口打开
app = Application('uia').start("notepad.exe")
time.sleep(3)
app = Application('uia').connect(class_name="Notepad")
win = app['无标题 - Notepad']
print(win)
print(app.process)
win.print_control_identifiers()

6.5.3运行代码

1.运行代码,右键Run'Test',就可以看到控制台输出,如下图所示:

2.运行代码后电脑端的动作(启动记事本)。如下图所示:

好了到此打印控件菜单结构树,就大功告成了,下一步我们只需要将其保存就可以了,灰常简单哦!!!

7.保存控件菜单结构树

7.1print_control_identifiers()源码

忙着解决问题,都没有来得及查看一下print_control_identifiers()的源码,如下:

代码语言:javascript
代码运行次数:0
运行
复制
    def print_control_identifiers(self, depth=None, filename=None):
        """
        Prints the 'identifiers'

        Prints identifiers for the control and for its descendants to
        a depth of **depth** (the whole subtree if **None**).

        .. note:: The identifiers printed by this method have been made
               unique. So if you have 2 edit boxes, they won't both have "Edit"
               listed in their identifiers. In fact the first one can be
               referred to as "Edit", "Edit0", "Edit1" and the 2nd should be
               referred to as "Edit2".
        """
        if depth is None:
            depth = sys.maxsize
        # Wrap this control
        this_ctrl = self.__resolve_control(self.criteria)[-1]

        # Create a list of this control and all its descendants
        all_ctrls = [this_ctrl, ] + this_ctrl.descendants()

        # Create a list of all visible text controls
        txt_ctrls = [ctrl for ctrl in all_ctrls if ctrl.can_be_label and ctrl.is_visible() and ctrl.window_text()]

        # Build a dictionary of disambiguated list of control names
        name_ctrl_id_map = findbestmatch.UniqueDict()
        for index, ctrl in enumerate(all_ctrls):
            ctrl_names = findbestmatch.get_control_names(ctrl, all_ctrls, txt_ctrls)
            for name in ctrl_names:
                name_ctrl_id_map[name] = index

        # Swap it around so that we are mapped off the control indices
        ctrl_id_name_map = {}
        for name, index in name_ctrl_id_map.items():
            ctrl_id_name_map.setdefault(index, []).append(name)

        def print_identifiers(ctrls, current_depth=1, log_func=print):
            """Recursively print ids for ctrls and their descendants in a tree-like format"""
            if len(ctrls) == 0 or current_depth > depth:
                return

            indent = (current_depth - 1) * u"   | "
            for ctrl in ctrls:
                try:
                    ctrl_id = all_ctrls.index(ctrl)
                except ValueError:
                    continue
                ctrl_text = ctrl.window_text()
                if ctrl_text:
                    # transform multi-line text to one liner
                    ctrl_text = ctrl_text.replace('\n', r'\n').replace('\r', r'\r')

                output = indent + u'\n'
                output += indent + u"{class_name} - '{text}'    {rect}\n"\
                    "".format(class_name=ctrl.friendly_class_name(),
                              text=ctrl_text,
                              rect=ctrl.rectangle())
                output += indent + u'{}'.format(ctrl_id_name_map[ctrl_id])

                title = ctrl_text
                class_name = ctrl.class_name()
                auto_id = None
                control_type = None
                if hasattr(ctrl.element_info, 'automation_id'):
                    auto_id = ctrl.element_info.automation_id
                if hasattr(ctrl.element_info, 'control_type'):
                    control_type = ctrl.element_info.control_type
                    if control_type:
                        class_name = None  # no need for class_name if control_type exists
                    else:
                        control_type = None # if control_type is empty, still use class_name instead
                criteria_texts = []
                if title:
                    criteria_texts.append(u'title="{}"'.format(title))
                if class_name:
                    criteria_texts.append(u'class_name="{}"'.format(class_name))
                if auto_id:
                    criteria_texts.append(u'auto_id="{}"'.format(auto_id))
                if control_type:
                    criteria_texts.append(u'control_type="{}"'.format(control_type))
                if title or class_name or auto_id:
                    output += u'\n' + indent + u'child_window(' + u', '.join(criteria_texts) + u')'

                if six.PY3:
                    log_func(output)
                else:
                    log_func(output.encode(locale.getpreferredencoding(), errors='backslashreplace'))

                print_identifiers(ctrl.children(), current_depth + 1, log_func)

        if filename is None:
            print("Control Identifiers:")
            print_identifiers([this_ctrl, ])
        else:
            log_file = codecs.open(filename, "w", locale.getpreferredencoding())

            def log_func(msg):
                log_file.write(str(msg) + os.linesep)
            log_func("Control Identifiers:")
            print_identifiers([this_ctrl, ], log_func=log_func)
            log_file.close()

    print_ctrl_ids = print_control_identifiers
    dump_tree = print_control_identifiers

print_ctrl_ids 和 dump_tree 实现的功能与print_control_identifiers等价,都是调用的print_control_identifiers 方法。 用2个参数:

  • depth 查找框架深度,默认全部查找
  • filename 保存本地文件名称

7.2保存到本地文件

1.我们把打印的控件结构树内容保存到本地txt,这样查看更方便,直接CTRL+F查找即可。

7.2.1代码设计

7.2.2参考代码

代码语言:javascript
代码运行次数:0
运行
复制
# -*- coding:utf-8 -*-

# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2025-02-12
@author: 北京-宏哥
北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!)
Project: PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构(详细教程)
'''

# 3.导入模块
from pywinauto import Application
import time

# 通过窗口打开
app = Application('uia').start("notepad.exe")
time.sleep(3)
app = Application('uia').connect(class_name="Notepad")
win = app['无标题 - Notepad']
print(win)
print(app.process)
win.print_control_identifiers()
win.print_ctrl_ids(filename="bjhg.txt")

7.2.3运行代码

1.运行代码,右键Run'Test',就可以看到控制台输出,如下图所示:

2.运行代码后电脑端的动作(启动记事本)。如下图所示:

3.在windows上运行后文件写入的中文内容有乱码,如下图所示:

4.重新设保存文件默认编码可以解决此问题。

7.2.4代码设计

7.2.5参考代码

代码语言:javascript
代码运行次数:0
运行
复制
# -*- coding:utf-8 -*-

# 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行

# 2.注释:包括记录创建时间,创建人,项目名称。
'''
Created on 2025-02-12
@author: 北京-宏哥
北京宏哥(微信搜索:北京宏哥,关注宏哥,提前解锁更多测试干货!)
Project: PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构(详细教程)
'''

# 3.导入模块
from pywinauto import Application
import time
import locale


def getpreferredencoding(do_setlocale = True):
    return "utf-8"


# 设置保存文件编码 "utf-8"
locale.getpreferredencoding = getpreferredencoding
print(locale.getpreferredencoding())

# 通过窗口打开
app = Application('uia').start("notepad.exe")
time.sleep(3)
app = Application('uia').connect(class_name="Notepad")
win = app['无标题 - Notepad']
print(win)
print(app.process)
win.print_control_identifiers()
win.print_ctrl_ids(filename="bjhg.txt")

7.2.6运行代码

1.运行代码,右键Run'Test',就可以看到控制台输出,如下图所示:

2.运行代码后电脑端的动作(启动记事本)。如下图所示:

8.小结

 今天主要讲解和分享的是打印控件菜单结构树的方法:print_control_identifiers()在Windows10系统和Windows11系统上遇到的问题:pywinauto.findwindows.ElementNotFoundError: {'best_match': 'Untitled - Notepad', 'backend': 'uia', 'process': 31680} ,如何遇到,然后宏哥是怎么一步一步解决的,但是其中的原理宏哥还是有点懵,好在是问题暂时解决了。其实回过头来看走过的路,其中有一些走弯路了,当时由于宏哥急于解决问题,没有仔细思考,第一步已经发现进程号都不一样了,什么等待啊、改路径等等全是白扯,根本解决不了问题。现在问题解决了,按照解决问题思路宏哥倒退一下是原理:PC端程序启动后,慢慢在后台加载界面程序,这时宏哥加了等待,然后等待程序加载完成,宏哥然后连接这个加载好的应用程序,这样就确保PC端启动的程序和连接的程序一样(进程号一致),然后执行控件结构树的打印,就不会找不到了。因此等待和连接二者缺一不可,前边宏哥也将而这分开实践了,解决不了问题,仍然报错。二者结合问题解决。

好了,关于打印和保存控件菜单结构树以及不同操作系统遇到的问题,都得到完美解决,仅供参考学习,小伙伴或者童鞋们,有其他更好的解决办法可以给宏哥留言评论哈!时间不早了今天就分享到这里,感谢你耐心地阅读!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构之ElementNotFoundError(详细教程)
其实前边的文章宏哥已经在控制台打印过控件菜单树结构,只是没有将其保存到文件中。只需要一个方法即可。在pywinauto中可以使用 print_control_identifiers() 方法打印控件菜单树结构,这对我们查找控件非常方便。宏哥今天将其单独拎出来是因为Windows10系统和Windows11系统会有一个坑,而且宏哥掉里边了,查了好多资料都没有找到解决办法,最后还好通过自己各种尝试将坑填平,成功爬出来了。其实前边已经遇到了打开记事本最后替换成了notepad++。今天跟随宏哥一步步入坑,然后再一步步填坑,最后成功解决。
北京-宏哥
2025/05/21
3360
PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构之ElementNotFoundError(详细教程)
PC端自动化测试实战教程-2-pywinauto 启动PC端应用程序 - 上篇(详细教程)
经过上一篇的学习、介绍和了解,想必小伙伴或者童鞋们,已经见识到pywinauto的强大了,今天继续介绍pywinauto,上一篇已经可以打开计算器了,这里宏哥在提供其他方法进行打开计算器和非电脑自带程序。pywinauto 可以启动电脑自带的应用程序,也可以启动电脑安装的应用程序。
北京-宏哥
2025/01/17
3250
PC端自动化测试实战教程-2-pywinauto 启动PC端应用程序 - 上篇(详细教程)
windows 桌面GUI自动化-4. pywinauto 操作窗口控件child_window()
也可以通过print_ctrl_ids()方法 (另外一个print_control_identifiers() 功能一样)查看当前窗口下的控件
上海-悠悠
2023/08/25
3.2K0
windows 桌面GUI自动化-4. pywinauto 操作窗口控件child_window()
PC 自动化测试入门 - pywinauto 上篇:初识
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2024/04/26
6K2
PC 自动化测试入门 - pywinauto 上篇:初识
Pywinauto之Windows UI 自动化1
前言,公司要搭建自动化测试环境,涉及到对设备软件的烧录操作,在网上找了些资料,发现pywinauto这个python库,能很好的支持PC端跑自动化,为此,记录下学习过程
用户6367961
2019/09/29
9.3K1
Pywinauto之Windows UI 自动化1
PC端自动化测试实战教程-4-pywinauto 操作PC端应用程序窗口 - 上篇(详细教程)
前几篇通过宏哥的讲解和分享,已经知道如何将PC端的应用程序启动,以及如何连接已启动的应用程序,那么启动和连接上之后呢?不用说当然是操作应用程序了,怎么操作呢?请听宏哥给你娓娓道来,所以今天主要是讲解和分享一下如何操作PC端应用程序的窗口。
北京-宏哥
2025/01/21
1.1K0
PC端自动化测试实战教程-4-pywinauto 操作PC端应用程序窗口 - 上篇(详细教程)
PC端自动化测试实战教程-3-pywinauto 启动PC端应用程序 - 下篇(详细教程)
经过上一篇的学习、介绍和了解,pywinauto的强大,不言而喻吧!宏哥讲解和分享的是电脑自带和安装的应用程序。有些小伙伴或者童鞋们已经迫不及待地私信宏哥,如果在电脑中这个应用程序已经启用了,我如何去启动这个已经启动的应用程序呢?各位别急,宏哥今天就会讲解和分享如何启动PC端已经启动的应用程序。
北京-宏哥
2025/01/20
4170
PC端自动化测试实战教程-3-pywinauto 启动PC端应用程序 - 下篇(详细教程)
PC端自动化测试实战教程-5-pywinauto 操作PC端应用程序窗口 - 下篇(详细教程)
上一篇宏哥主要讲解和介绍了如何获取PC端应用程序窗口信息和如何连接窗口对其进行操作的常用的几种方法。今天宏哥接着讲解和分享一下窗口的基本操作:最大化、最小化、恢复正常、关闭窗口、获取窗口状态和获取窗口坐标。以及窗口的其他打开方法和选择方法。
北京-宏哥
2025/05/09
4640
PC端自动化测试实战教程-5-pywinauto 操作PC端应用程序窗口 - 下篇(详细教程)
pywinauto教程
转:pywinauto教程https://blog.csdn.net/weixin_40161673/article/details/83246861
墨文
2020/02/28
8.9K0
pywinauto教程
windows 桌面GUI自动化- 8.pywinauto 获取控件属性和文本内容
上海-悠悠
2023/08/25
1.7K0
windows 桌面GUI自动化- 8.pywinauto 获取控件属性和文本内容
PC端自动化测试实战教程-5-pywinauto 操作PC端应用程序窗口 - 下篇(详细教程)
上一篇宏哥主要讲解和介绍了如何获取PC端应用程序窗口信息和如何连接窗口对其进行操作的常用的几种方法。今天宏哥接着讲解和分享一下窗口的基本操作:最大化、最小化、恢复正常、关闭窗口、获取窗口状态和获取窗口坐标。以及窗口的其他打开方法和选择方法。
北京-宏哥
2025/01/22
7130
PC端自动化测试实战教程-5-pywinauto 操作PC端应用程序窗口 - 下篇(详细教程)
聊聊 PC 端自动化最佳方案 - Pywinauto
有小伙伴后台给我留言,说「 pywinauto 」作为 WinAppDriver 的替代方案,也能完美完成 PC 端的自动化
AirPython
2021/08/27
3K0
聊聊 PC 端自动化最佳方案 - Pywinauto
pywinauto桌面应用自动化入门篇
本案例因为start方法无法启动应用程序,所以我这里使用了os.system去启动的应用程序
懿曲折扇情
2022/10/28
7K0
pywinauto桌面应用自动化入门篇
PC端自动化测试实战教程-1-pywinauto 环境搭建(详细教程)
之前总有人在群里或者私信留言问:Windows系统安装的软件如何自动化测试呢?因为没有接触过或者遇到过,所以说实话宏哥当时也不清楚怎么实现,怎么测试。然而在一次偶然的机会接触到了Python的一个模块说是它可以实现Microsoft Windows GUI自动化测试,宏哥就想试一下是不是可以实现了,于是就边学习边记录供小伙伴或者童鞋们学习参考。
北京-宏哥
2025/01/13
4.3K0
PC端自动化测试实战教程-1-pywinauto 环境搭建(详细教程)
windows 桌面GUI自动化-3. pywinauto 操作指定window窗口
pywinauto 操作GUI应用程序上的元素,需先找到指定窗口,基于窗口查找框架再操作。
上海-悠悠
2023/08/25
4.2K0
windows 桌面GUI自动化-3. pywinauto 操作指定window窗口
PC端自动化测试实战教程-7-pywinauto等待方法大集合 (详细教程)
经过上一篇的学习和讲解想必小伙伴或者童鞋们已经意识到等待的重要性了吧。宏哥在上一篇中在start()后,加入适当的等待时间(如time.sleep()),让应用程序有足够的时间初始化窗口和UI元素。之前我们在做web和app的ui自动化过程中,常用到等待机制,那PC端自动化有这个方法吗?答案是肯定的,python这么强大,肯定是有方法的。今天就跟随宏哥来一起看一下PC端自动化是如何等待的。应用程序行为通常不稳定,您的脚本需要等待,直到出现新窗口或关闭/隐藏现有窗口。 pywinauto可以隐式地(默认超时)灵活地等待对话框初始化,或者明确地使用专用方法/函数来帮助您使代码更容易和更可靠。
北京-宏哥
2025/05/28
4270
PC端自动化测试实战教程-7-pywinauto等待方法大集合 (详细教程)
Pywinauto之Windows UI自动化5
在时钟附近有表示正在运行的应用程序的图标,该区域通常被称为“系统托盘”,也称为通知区域。该区域的访问,可以通过启动“Explorer.exe"这个应用程序,可以在'任务栏'这个窗口中找到有标题为'用户提示通知区域'的工具栏控件。
用户6367961
2021/06/21
1.9K0
Pywinauto之Windows UI自动化5
PC端自动化测试(三)
在时钟附近有表示正在运行的应用程序的图标,也就是「系统托盘」,也被称为「通知区域」。
zx钟
2020/04/08
1.6K0
windows 桌面GUI自动化- 11.pywinauto 窗口和控件截图capture_as_image()
上海-悠悠
2023/09/11
7070
windows 桌面GUI自动化- 11.pywinauto 窗口和控件截图capture_as_image()
windows 桌面GUI自动化- 14.pywinauto 找到多个相同控件使用found_index
pywinauto 在查找到多个相同控件时操作会报错,可以使用found_index 选择其中的一个
上海-悠悠
2023/09/11
1.3K1
windows 桌面GUI自动化- 14.pywinauto 找到多个相同控件使用found_index
推荐阅读
相关推荐
PC端自动化测试实战教程-6-pywinauto 打印和保存控件菜单树结构之ElementNotFoundError(详细教程)
更多 >
目录
  • 1.简介
  • 2.控件操作
  • 3.起因
  • 4.Windows10系统
    • 4.1代码设计
    • 4.2参考代码
    • 4.3运行代码
  • 5.Windows11系统
    • 5.1运行代码
    • 5.2报错分析
  • 6.填坑实践
    • 6.1加等待
      • 6.1.1代码设计
      • 6.1.2参考代码
      • 6.1.3运行代码
    • 6.2改路径
      • 6.2.1参考代码
    • 6.3 connect()
      • 6.3.1参考代码
    • 6.4 connect()和visible_only参数
      • 6.4.1代码设计
      • 6.4.2参考代码
      • 6.4.3运行代码
    • 6.5 connect()和等待
      • 6.5.1代码设计
      • 6.5.2参考代码
      • 6.5.3运行代码
  • 7.保存控件菜单结构树
    • 7.1print_control_identifiers()源码
    • 7.2保存到本地文件
      • 7.2.1代码设计
      • 7.2.2参考代码
      • 7.2.3运行代码
      • 7.2.4代码设计
      • 7.2.5参考代码
      • 7.2.6运行代码
  • 8.小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档