【Python】Spy++使用
SPY++的使用和Python操作
- 1、spy++的基本操作
- 1.1 窗口属性查找
- 1.2 窗口spy++定位
- 2、python与spy++
- Source Code
- Use
- 下载 Spy++:文末公众号回复 210127 获取压缩包
1、spy++的基本操作
1.1 窗口属性查找
拖住中间的“寻找工具”放到想要定位的软件上,然后松开
- 以微信为例,我们会得到“微信”这个窗口的句柄,为“00031510”,注意这个句柄是“十六进制”,即“0x31510”。
- 点击ok我们会看到更详细的属性信息
1.2 窗口spy++定位
- 同理拖放到“微信”上,获取到“微信”的界面
- 点击ok,会直接定位到“微信”
- 在这里我们会看到一条信息
- 00031510 “微信” WeChatMainWndForPC
– 00031510:代表十六进制的窗口句柄
– 微信:代表窗口标题
– WeChatMainWndForPC:代表窗口的类名
2、python与spy++
Source Code
#!/usr/bin/python
# -*- coding: utf-8 -*-
# @Time : 2021/1/27 10:50
# @Author : SandQuantimport collections
from win32 import win32gui
import pyautogui
import sysclass PySpy(object):Window = collections.namedtuple('Window', ['caption', 'class_name', 'hwnd_py', 'hwnd_spy'])def __init__(self):pass@classmethoddef window_attr(cls, hwnd_py):"""显示窗口的属性:param hwnd_py: 窗口句柄(十进制):return: Window"""return cls.Window(caption=win32gui.GetWindowText(hwnd_py),class_name=win32gui.GetClassName(hwnd_py),hwnd_py=hwnd_py,hwnd_spy=hex(hwnd_py),)@classmethoddef show_top_windows(cls):"""列出所有的顶级窗口及属性:return: 全部的顶层窗口及对应属性"""containers = []win32gui.EnumWindows(lambda hwnd, param: param.append(cls.window_attr(hwnd)), containers)return containers@classmethoddef find_top_window(cls, caption) -> list:"""查找窗体:param caption: 窗口标题部分文字:return:"""return [w for w in cls.show_top_windows() if caption in w.caption]@classmethoddef find_sub_windows(cls, hwnd_py=None, class_name=None, caption=None, index=None):"""返回窗体下全部的子窗体,默认主窗体下的窗体:param hwnd_py: 句柄 十进制:param class_name: 窗口类名,返回特定类名:param caption: 窗口标题,返回特定标题:param index: 位置,返回特定位置的窗口:return: 包含属性的全部子窗口"""num = 0handle = 0sub_windows = []while True:# find next handle, return HwndPyhandle = win32gui.FindWindowEx(hwnd_py, handle, class_name, caption)if handle == 0:# no more handlebreak# get handle attributionattr = cls.window_attr(handle)# append to listsub_windows.append(tuple(list(attr) + [num]))num += 1if index is not None:return sub_windows[index]else:return sub_windows@classmethoddef show_all_windows(cls, window=None, handle_list=None, handle_dict=None):"""生成窗口全部对应的关系:param window: 目标父窗口:param handle_list: 默认为[[None]]:param handle_dict: 用于存放对应关系:return: 返回目标窗口下全部子父窗口的字典"""if not handle_list and not handle_dict:handle_list = [[None]]handle_dict = dict()sys.setrecursionlimit(1000000)if window:handle_list[-1][0] = windowhandles = cls.find_sub_windows(handle_list[-1][0][2])else:handles = cls.find_sub_windows()for handle in handles:handle_dict[handle] = window# 这个根节点已经遍历完,删除del handle_list[-1][0]# 如果有叶节点,非空,则加入新的叶节点if handles:handle_list.append(handles)# 删除已被清空的根handle_list = [HandleGroup for HandleGroup in handle_list if HandleGroup]# 如果还有根就继续遍历,否则输出树if handle_list:return cls.show_all_windows(window=handle_list[-1][0], handle_list=handle_list, handle_dict=handle_dict)else:return handle_dict@classmethoddef find_handle_path(cls, hwnd_spy, num):"""寻找特定窗口的寻找路径找到全部层级的对应关系,然后反向搜索:param hwnd_spy: 窗口句柄(十六进制):param num: 窗口所属index,在spy++内查看:return:parent_window:顶层窗口target_path:路径的index"""all_path = cls.show_all_windows()key = tuple(list(cls.window_attr(int(hwnd_spy))) + [num])handle_path = [key]while True:key = all_path[key]if not key:handle_path = handle_path[::-1]parent_window = handle_path[0]target_path = [(i[-1]) for i in handle_path[1:]]return parent_window, target_pathhandle_path.append(key)@classmethoddef find_target_handle(cls, window, path):"""递归寻找子窗口的句柄:param window: 祖父窗口的完整句柄 (WindowName, ClassName, HwndPy, HwndSpy):param path: 子窗口列表:return: 目标窗口的完整属性"""for i in range(len(path)):window = cls.find_sub_windows(window[2], index=path[i])return window
Use
1、获取窗体属性
# 获取句柄1902690的属性
window = PySpy.window_attr(hwnd_py=1902690)
print(window)
Window(caption='百度云', class_name='ATL:011386F8', hwnd_py=1902690, hwnd_spy='0x1d0862')
2、获取全部顶层窗体
# 获取全部顶层窗体
windows = PySpy.show_top_windows()[:5]
for w in windows:print(w)
Window(caption='', class_name='ForegroundStaging', hwnd_py=66032, hwnd_spy='0x101f0')
Window(caption='', class_name='ForegroundStaging', hwnd_py=65982, hwnd_spy='0x101be')
Window(caption='', class_name='tooltips_class32', hwnd_py=65836, hwnd_spy='0x1012c')
Window(caption='', class_name='tooltips_class32', hwnd_py=65844, hwnd_spy='0x10134')
Window(caption='', class_name='tooltips_class32', hwnd_py=65856, hwnd_spy='0x10140')
3、查找指定的顶层窗体
# 查找顶层窗体
result = PySpy.find_top_window(caption='spy++')
print(result)
[Window(caption='spy++', class_name='CabinetWClass', hwnd_py=9571640, hwnd_spy='0x920d38')]
4、查找特定父窗体下全部子窗体
# 查找特定句柄下全部子窗体
window = PySpy.find_sub_windows(hwnd_py=9571640)
for w in windows:print(w)
Window(caption='', class_name='ForegroundStaging', hwnd_py=66032, hwnd_spy='0x101f0')
Window(caption='', class_name='ForegroundStaging', hwnd_py=65982, hwnd_spy='0x101be')
Window(caption='', class_name='tooltips_class32', hwnd_py=65836, hwnd_spy='0x1012c')
Window(caption='', class_name='tooltips_class32', hwnd_py=65844, hwnd_spy='0x10134')
Window(caption='', class_name='tooltips_class32', hwnd_py=65856, hwnd_spy='0x10140')
5、获取全部窗体父子对应关系
# 生成窗口全部对应的关系
windows = PySpy.show_all_windows(window=('spy++', 'CabinetWClass', 9571640, '0x920d38'))
for w in windows.items():print(w)
(('UIRibbonDockLeft', 'UIRibbonCommandBarDock', 1838390, '0x1c0d36', 0), ('spy++', 'CabinetWClass', 9571640, '0x920d38'))
(('UIRibbonDockRight', 'UIRibbonCommandBarDock', 1773536, '0x1b0fe0', 1), ('spy++', 'CabinetWClass', 9571640, '0x920d38'))
(('UIRibbonDockTop', 'UIRibbonCommandBarDock', 2756588, '0x2a0fec', 2), ('spy++', 'CabinetWClass', 9571640, '0x920d38'))
...
(('', 'ScrollBar', 52956100, '0x3280bc4', 0), ('', 'CtrlNotifySink', 3607746, '0x370cc2', 1))
(('', 'ReBarWindow32', 11603876, '0xb10fa4', 0), ('', 'WorkerW', 2755884, '0x2a0d2c', 1))
(('', 'ToolbarWindow32', 2427436, '0x250a2c', 0), ('', 'ReBarWindow32', 11603876, '0xb10fa4', 0))
6、获取特定窗体的查找路径
# 寻找特定窗口的寻找路径
parent, pth = PySpy.find_handle_path(hwnd_spy=0xb10fa4, num=0)
print(parent, pth)
('spy++', 'CabinetWClass', 9571640, '0x920d38', 232) [5, 1, 0]
7、根据查找路径获取到句柄信息(6的逆过程)
# 根据顶层窗体和路径 寻找子窗口的句柄
window = PySpy.find_target_handle(window=parent, path=pth)
print(window)
('', 'ReBarWindow32', 11603876, '0xb10fa4', 0)
8、根据窗体句柄,找到窗体位置
# 根据句柄定位窗体
x, y, m, n = win32gui.GetWindowRect(9571640)
pyautogui.moveTo((x + m) / 2, (y + n) / 2)
欢迎关注~ SandQuant 专注于全球金融数据和量化投资策略
【Python】Spy++使用相关推荐
- python下的spectral模块(高光谱图像处理)
Spectral Python (SPy)是一个用于处理高光谱图像数据的纯Python模块.它具有读取.显示.操作和分类高光谱图像的功能. 之所以用它是因为这个对多波段图像的支持更好 参考 一.SPy ...
- spectral安装
Spectral Python (SPy) 是一个纯 Python 模块,用于处理高光谱图像数据.它具有读取.显示.操作和分类高光谱图像的功能. SPy 需要 Python 并依赖于其他几个免费提供的 ...
- 1.2 InSAR数据处理之软件介绍
本节内容主要分为两部分,分别是: 1.Windows操作系统下的软件介绍. 2.Linux系统下的软件介绍. 许多InSAR数据处理软件只能安装于Linux操作系统上,但有一部分软件既能够支持Linu ...
- 有用的URL,大量的干货!!!!!!!!!!!!
这篇不算提供技术,笔者之前收藏了很多有用的学习资料URL,拿出来供大家共享!!!!!!!!! PythonTab:Python中文开发者社区门户 http://www.pythontab.com/ P ...
- Introspection in Python How to spy on your Python objects Guide to Python introspection
什么是自省? 在日常生活中,自省(introspection)是一种自我检查行为. 在计算机编程中,自省是指这种能力:检查某些事物以确定它是什么.它知道什么以及它能做什么.自省向程序员提供了极大的灵活 ...
- 在 Python 中使用蒙特卡罗方法预测股票价格,使用蒙特卡罗模拟确定明年 SPY 最有可能的价格
股票市场是历史上研究最多的领域之一.几十年来,人们一直在努力预测未来的价格.大多数人(如果不是全部)都在为这项任务而苦苦挣扎,因为股票市场是一个随机过程.由于其随机性,随机过程本质上很难或不可能准确预 ...
- 破纪录了!用 Python 实现自动扫雷!
用Python+OpenCV实现了自动扫雷,突破世界记录,我们先来看一下效果吧. 中级 - 0.74秒 3BV/S=60.81 相信许多人很早就知道有扫雷这么一款经典的游(显卡测试)戏(软件),更是有 ...
- Python+OpenCV实现自动扫雷,挑战扫雷世界记录!
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转载自知乎Artrix https://zhuanlan.zh ...
- Python+OpenCV实现自动扫雷,创造属于自己的世界记录!
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转载自知乎Artrix https://zhuanlan.zh ...
- python语言type board_菜鸟学Python,双手奉上老司机给上路新手总结的Python实战问题……...
针对Python这一话题每天后台都会有不少小伙伴提出问题,下面我就将这些问题进行汇整,产出"Python实战问题篇",我认为这些问题非常具有代表性,希望可以帮到大家. 第一类问题: ...
最新文章
- TensorFlow Serving 尝尝鲜
- 17、有名管道与无名管道之间的区别
- WPF 文本框添加水印效果
- wampserver3.0.6 外网 不能访问
- linux系统打开m3u8文件,M3U8 文件扩展名: 它是什么以及如何打开它?
- c语言交通违章编程代码,C语言程序设计之交通处罚单管理系统 报告(内含代码).doc...
- 哈希桶 entry_聊一聊面试常问的几大哈希算法问题,这些你都会了嘛??
- paip.mysql error2003 Can''t connect to MySQL server on localhost (10061)的解决
- 百度换肤怎么实现的html,JavaScript 实现百度换肤功能
- 参考文献中英文人名_参考文献中英文人名的写法
- 相机等效焦距和视场角计算
- Vulkan规范笔记(一) 第一章至第六章
- chrome插件安装
- Ant Design 编写登录和注册页面
- openfalcon 组件监控_使用滴滴云快速搭建 Open-Falcon 监控平台
- 本地git的分支名称变空的处理方法
- 仿微同商城后台API
- ip地址大全_2020全球公共 DNS 服务器 IP 地址大全
- 【NLP】第12章 检测客户情绪以做出预测
- 什么是电力物联网?为什么要建造电力物联网云平台?——安科瑞 严新亚