Python 如何准确获取 Spotify 窗口标题,避免匹配其他窗口?
可以通过窗口所属的进程定位 Spotify,再读取窗口标题。仅凭标题中是否包含 " - ",无法可靠区分 Spotify 和其他应用。读取标题时也无需让窗口获得焦点。
原问题没有明确操作系统。下面以 Windows 桌面环境为例;macOS 和 Linux 需要使用各自的窗口管理接口。
为什么现有筛选会误匹配?
getAllTitles() 返回的是窗口标题字符串,无法判断每个标题属于哪个应用。浏览器、编辑器和其他播放器的标题都可能包含 " - ",即使继续扩充 ignore 列表,也很难覆盖所有情况。
此外,忽略列表中包含 "Spotify"。如果目标窗口的标题恰好包含这个词,也会被排除。
可以根据窗口所属的进程 ID 筛选:先找到 Spotify 进程,再保留属于这些进程的窗口。操作系统层面仍可能需要枚举窗口,但无需再根据标题内容猜测应用身份。
Windows 下按进程 ID 获取标题
示例使用 psutil 获取进程信息,使用 pywin32 枚举窗口并读取标题。先安装依赖:
python -m pip install psutil pywin32
代码假设目标是桌面 Spotify 客户端,且进程名称为 Spotify.exe。如果任务管理器中显示的名称不同,需要修改匹配条件;浏览器中的 Spotify 网页播放器不适用这个条件。
import time
import psutil
import pywintypes
import win32gui
import win32process
def get_spotify_pids():
pids = set()
for process in psutil.process_iter(["pid", "name"]):
try:
name = process.info["name"] or ""
if name.casefold() == "spotify.exe":
pids.add(process.info["pid"])
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
return pids
def get_spotify_windows():
pids = get_spotify_pids()
windows = []
if not pids:
return windows
def visit_window(hwnd, _):
try:
if not win32gui.IsWindowVisible(hwnd):
return True
_, pid = win32process.GetWindowThreadProcessId(hwnd)
if pid not in pids:
return True
title = win32gui.GetWindowText(hwnd)
if title:
windows.append((hwnd, title))
except pywintypes.error:
# 窗口可能在枚举期间关闭。
pass
return True
win32gui.EnumWindows(visit_window, None)
return windows
previous_titles = None
try:
while True:
windows = get_spotify_windows()
titles = tuple(sorted({title for _, title in windows}))
if titles != previous_titles:
print("\n".join(titles) if titles else "未找到可读取标题的 Spotify 窗口")
previous_titles = titles
time.sleep(1)
except KeyboardInterrupt:
pass
示例保留了所有符合条件的窗口,没有直接选取第一个。Spotify 可能有多个进程或窗口。如果返回多个候选窗口,可以先查看 (hwnd, title),再根据观察到的窗口特征补充筛选条件。
程序每秒重新查询一次,只在标题集合发生变化时输出,无需反复清空终端,也不会持续打印相同标题。
窗口标题能否可靠表示当前歌曲?
这段代码解决了标题来自哪个应用的问题,但无法保证标题始终包含歌曲信息。暂停播放、客户端界面状态或版本差异都可能影响窗口暴露的标题。
可以先输出原始标题,确认当前客户端实际提供的内容。如果标题确实采用 艺术家 - 歌曲名 的形式,再进行解析。不过,艺术家和歌曲名称本身也可能含有 " - ",简单调用 split() 无法保证字段划分准确。需要稳定、结构化的歌曲数据时,应考虑播放器提供的播放状态接口,不宜将窗口标题当作固定的数据格式。
另外,原始代码粘贴后缺少 while、for 和 if 下方的缩进。如果实际文件也是这样,需要先修正缩进才能运行。
备注:内容仅供参考。
