Python自动化(1)——获取窗口句柄

Python自动化(1)——获取窗口句柄

前言
在现代生活中,人们的工作往往有很大的重复性。可能一个工作,会有90%的相似性,这时候,就会思考能否通过程序来代替人工。
Python作为近几年来大火的编程语言,其便捷性和高效性,使得我首选这个语言来实现自动化。其中,有很多公用的库,能大大提高开发的效率
(题外话:选择python语言,是因为这顺便也能让我学习一下python,说明一下,在写本自动化框架之前,我只用python写过一个公司下班和吃饭提醒机器人[基于企微机器人],因此本文难度不会很大,是初级篇[但是至少得入门,知道python的语法,会安装python库什么的])

Python版本:3.9.10
用到的库:time,pywin32(需安装),pyautogui(需安装),pyperclip(需安装)

获取窗口句柄的方式

获取窗口句柄一般有两种方法,第一种是直接通过窗口的标题获取;第二种是通过判断当前鼠标悬停的位置,来获取鼠标悬停位置下的窗口句柄。

通过窗口标题获取窗口句柄

def bindHwnd_1(self, windowName):
self._hwnd = win32gui.FindWindow(None, windowName)
print(‘hwnd:’+str(self._hwnd))
self._thread_id, self._process_id = win32process.GetWindowThreadProcessId(self._hwnd)
self._threadName = psutil.Process(self._process_id).name()
print("self._thread_id: "+str(self._thread_id))
print("self._threadName: "+str(self._threadName))
return self._hwnd

例子:新建一个文本文档并打开,通过窗口标题获取窗口句柄。首先需要获取窗口标题,打开任务管理器,找到记事本,打开记事本的子标题,里面“新建文本文档.txt – 记事本”就是窗口标题
在这里插入图片描述
测试代码以及结果:
在这里插入图片描述
使用这种方法,需要获取窗口标题,有时候不知道窗口标题,或者不想打开任务管理器找,可以通过代码遍历全部的窗口句柄,找到对应的窗口标题。

通过上面的方法,可以获取全部的窗口标题,但是此时就会出现第二个问题,那就是如果出现多个窗口标题相同的情况那该怎么办。
如果通过上述的办法获取窗口句柄,会随机获取到多个相同窗口标题的其中一个窗口的句柄。也可以使用第二种方法,通过鼠标悬停获取窗口句柄。

通过鼠标悬停获取窗口句柄

def bindHwnd_2():
    point = win32api.GetCursorPos()
    _hwnd = win32gui.WindowFromPoint(point)
    print('hwnd:'+str(_hwnd))
    _thread_id, _process_id = win32process.GetWindowThreadProcessId(_hwnd)
    _threadName = psutil.Process(_process_id).name()
    print("_thread_id: "+str(_thread_id))
    print("_threadName: "+str(_threadName))
    return _hwnd

keyboard.add_hotkey('ctrl+b',bindHwnd_2,suppress = False)
keyboard.wait()

上述代码中,使用了keyboard库中的wait方法来使程序维持在运行状态,并添加了ctrl+b快捷键运行绑定窗口句柄的方法。运行后,将鼠标移动到文本文档的空白位置,并按下键盘ctrl+b快捷键。
运行结果:
在这里插入图片描述
此时得到了窗口句柄,但是对比上下两种方法,发现窗口句柄是不一样的,其实通过第一种方法获取的窗口句柄是一个窗口的根句柄,每个窗口的部件也是有窗口句柄的,称为子窗口句柄。
获取到根窗口句柄时,可以通过win32gui.EnumChildWindows方法来获取子窗口句柄。
测试代码:
在这里插入图片描述
这时,就看到了通过第二种方法获取到的是子窗口句柄,通过第一种方法获取到的是根窗口句柄。
注意:win32gui.EnumChildWindows会获取到所有的子窗口句柄,无论是子窗口句柄,还是子句柄的子句柄,都能获取到。

还可以通过一些工具来获取窗口的信息,最常用的软件有spy++

<think>我们正在处理一个关于浏览器自动化获取浏览器句柄的问题。用户希望了解如何使用自动化工具获取浏览器句柄。根据引用内容,我们可以参考几种方法:1.引用[1]和[2]提到了Selenium和Playwright这两种自动化工具,它们都可以用于浏览器自动化,但引用中没有直接提到获取句柄的方法。2.引用[4]详细介绍了使用Python的win32gui模块来获取窗口句柄(包括根窗口句柄和子窗口句柄)的方法,并提供了代码示例。因此,我们可以从两个方面来回答:一、使用专门的浏览器自动化工具(如Selenium、Playwright)提供的API来获取浏览器窗口句柄。二、使用操作系统级别的API(如Windows的win32gui)来获取窗口句柄。注意:用户的问题中并没有指定使用哪种编程语言或工具,所以我们需要提供多种方法。首先,我们介绍使用Selenium和Playwright的方法:-Selenium:在Selenium中,每个浏览器窗口(或标签页)都有一个窗口句柄(windowhandle),可以通过WebDriver对象的`window_handles`属性和`current_window_handle`属性来获取。-Playwright:Playwright中也有类似的概念,称为“上下文”(context)和“页面”(page),但也可以获取浏览器窗口句柄吗?实际上,Playwright更倾向于使用其自身的上下文和页面对象来控制,而不是直接使用操作系统的窗口句柄。其次,我们介绍使用操作系统API的方法(以Windows为例):-使用win32gui模块,通过枚举窗口来找到浏览器的窗口句柄。由于引用[4]提供了使用win32gui获取窗口句柄的详细代码,我们可以参考它。但是,用户的问题中特别提到了“浏览器句柄”,所以我们需要明确:-在浏览器自动化工具中,通常我们不需要直接操作操作系统的窗口句柄,因为工具已经提供了对窗口的抽象(如窗口句柄的字符串标识符)。-如果用户需要在操作系统级别操作浏览器窗口(例如,将浏览器窗口置于前台),那么可能需要使用操作系统API。因此,我们将分两部分回答:第一部分:使用浏览器自动化工具(如Selenium)获取窗口句柄(注意:这里的句柄自动化工具内部使用的标识符,不是操作系统级别的句柄)第二部分:使用操作系统API(如win32gui)获取浏览器窗口的操作系统句柄(HWND)接下来,我们按照这个思路组织回答,并尽可能提供代码示例。由于引用[4]是Python代码,我们主要用Python来演示。注意:用户可能使用不同的编程语言,但问题中引用的例子都是Python,所以我们用Python回答。</think>### 如何获取浏览器窗口句柄自动化方法 在浏览器自动化中,"句柄"(Handle)是操作系统标识窗口的唯一值。根据应用场景不同,可分为两种获取方式: #### 一、通过浏览器自动化工具获取(推荐) 适用于Web自动化测试场景(如Selenium/Playwright),获取的是工具内部的窗口标识符: 1. **Selenium 实现方法** 使用`window_handles`获取所有窗口句柄,`current_window_handle`获取当前句柄: ```python from selenium import webdriver driver = webdriver.Chrome() driver.get("https://example.com") # 获取当前窗口句柄 main_handle = driver.current_window_handle # 返回字符串类型句柄 print("当前句柄:", main_handle) # 打开新标签页 driver.execute_script("window.open('');") # 获取所有窗口句柄 all_handles = driver.window_handles # 返回句柄列表 print("所有句柄:", all_handles) # 切换到新窗口 driver.switch_to.window(all_handles[1]) ``` 2. **Playwright 实现方法** 通过`context.pages`获取页面对象: ```python from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch() context = browser.new_context() page = context.new_page() page.goto("https://example.com") # 获取页面对象(相当于句柄) current_page = page # 页面对象本身作为操作句柄 new_page = context.new_page() # 创建新窗口 all_pages = context.pages # 获取所有页面句柄 ``` #### 二、通过操作系统API获取(Windows) 适用于需要直接操作窗口的场景(如窗口置顶/截图),使用`win32gui`获取系统级HWND句柄: ```python import win32gui import win32con def get_browser_handles(): handles = [] # 枚举所有顶级窗口 def callback(hwnd, _): if win32gui.IsWindowVisible(hwnd): # 通过窗口标题过滤(示例:Chrome标题含"Google Chrome") title = win32gui.GetWindowText(hwnd) if "Chrome" in title and "Google Chrome" in title: handles.append(hwnd) win32gui.EnumWindows(callback, None) return handles # 获取所有Chrome窗口句柄 browser_handles = get_browser_handles() print("系统级句柄列表:", browser_handles) # 激活第一个浏览器窗口 if browser_handles: win32gui.ShowWindow(browser_handles[0], win32con.SW_MAXIMIZE) win32gui.SetForegroundWindow(browser_handles[0]) ``` > **关键区别说明** > - **自动化工具句柄**:字符串或对象,用于工具内部的窗口切换(如Selenium的`driver.switch_to.window()`)[^1] > - **系统级HWND句柄**:整数值,可直接操作窗口(移动/聚焦等),需配合`win32gui`等系统API[^4] #### 最佳实践建议 1. **Web自动化测试**优先使用Selenium/Playwright提供的句柄管理 2. **需操作系统级控制**时(如多进程协作),使用`win32gui`获取HWND 3. 混合使用时可通过浏览器进程ID关联两种句柄(如通过Selenium获取进程ID,再用`win32gui`查找对应窗口) --- ### 相关问题 1. 浏览器多标签页场景下如何精准定位特定页面的句柄? 2. 如何通过窗口句柄实现跨浏览器的自动化操作(如Chrome到Firefox)? 3. 在无头浏览器(Headless)模式下窗口句柄机制是否仍然有效? 4. 浏览器扩展程序窗口句柄获取有哪些特殊方法? [^1]: UI自动化测试之selenium工具(浏览器窗口的切换) [^4]: Python自动化(1)——获取窗口句柄
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值