PAYATHON 2026

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 下方的缩进。如果实际文件也是这样,需要先修正缩进才能运行。

备注:内容仅供参考。