You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python和AppleScript读取macOS应用菜单栏选项

读取macOS应用菜单栏选项的实现方法

完全可以通过AppleScript和Python实现自动读取任意应用全量菜单栏选项的需求,核心是调用macOS系统自带的无障碍(Accessibility)接口,不需要提前预知目标应用的菜单结构,具体实现方案如下:

方案1:原生AppleScript实现(无额外依赖)

该方案不需要安装任何第三方工具,直接通过系统自带的osascript即可运行,核心逻辑是递归遍历菜单栏的层级结构,自动抓取所有层级的菜单项文本。
运行前需要先给执行脚本的程序(终端、脚本编辑器等)开启辅助功能权限:打开系统设置>隐私与安全性>辅助功能,勾选对应程序即可,否则系统会拦截读取请求。
示例代码:

-- 修改为你要读取的目标应用名称
set targetAppName to "Safari"

tell application "System Events"
    tell application process targetAppName
        set frontmost to true
        -- 递归遍历菜单层级的通用方法
        on traverseMenuElements(elements, indentLevel)
            set outputList to {}
            repeat with elem in elements
                try
                    set elemName to name of elem
                    if elemName is not missing value and elemName ≠ "" then
                        -- 用缩进标识菜单层级
                        set indentText to ""
                        repeat indentLevel times
                            set indentText to indentText & "  "
                        end repeat
                        copy (indentText & elemName) to end of outputList
                        -- 存在子菜单则继续向下遍历
                        if exists menu of elem then
                            set subItems to every menu item of menu 1 of elem
                            set subOutput to my traverseMenuElements(subItems, indentLevel + 1)
                            set outputList to outputList & subOutput
                        end if
                    end if
                end try
            end repeat
            return outputList
        end traverseMenuElements

        -- 读取顶层菜单栏入口
        set topMenus to every menu of menu bar 1
        set allMenuOptions to my traverseMenuElements(topMenus, 0)
    end tell
end tell

-- 格式化输出结果
set AppleScript's text item delimiters to linefeed
return allMenuOptions as text

运行后会返回带缩进的层级化菜单列表,完整覆盖应用的所有菜单栏选项。

方案2:Python实现

Python侧有两种实现路径,不需要额外学习AppleScript语法也可以完成需求:

  • 轻量方案:通过subprocess模块调用系统osascript命令,执行上面的AppleScript逻辑并拿回解析结果,不需要额外安装第三方依赖,示例代码如下:
import subprocess

def get_app_menu_items(app_name: str) -> list[str]:
    as_script = f'''
    set targetAppName to "{app_name}"
    tell application "System Events"
        tell application process targetAppName
            set frontmost to true
            on traverseMenuElements(elements, indentLevel)
                set outputList to {{}}
                repeat with elem in elements
                    try
                        set elemName to name of elem
                        if elemName is not missing value and elemName ≠ "" then
                            set indentText to ""
                            repeat indentLevel times
                                set indentText to indentText & "  "
                            end repeat
                            copy (indentText & elemName) to end of outputList
                            if exists menu of elem then
                                set subItems to every menu item of menu 1 of elem
                                set subOutput to my traverseMenuElements(subItems, indentLevel + 1)
                                set outputList to outputList & subOutput
                            end if
                        end if
                    end try
                end repeat
                return outputList
            end traverseMenuElements
            set topMenus to every menu of menu bar 1
            set allMenuOptions to my traverseMenuElements(topMenus, 0)
        end tell
    end tell
    set AppleScript's text item delimiters to linefeed
    return allMenuOptions as text
    '''
    exec_result = subprocess.run(
        ["osascript", "-e", as_script],
        capture_output=True,
        text=True
    )
    if exec_result.returncode != 0:
        raise PermissionError(f"读取失败,请检查是否已授予辅助功能权限,错误信息:{exec_result.stderr}")
    return [line for line in exec_result.stdout.split("\n") if line.strip()]

# 调用示例
if __name__ == "__main__":
    menu_items = get_app_menu_items("Safari")
    for item in menu_items:
        print(item)
  • 原生API方案:安装pyobjc相关依赖后直接调用Cocoa层的无障碍接口,不需要内嵌AppleScript,灵活度更高,可以额外读取菜单项的可用状态、绑定快捷键等属性,适合复杂自动化场景,依赖安装命令为pip install pyobjc-framework-ApplicationServices pyobjc-framework-Cocoa。

注意事项

  • 权限是最常见的报错原因:第一次运行时系统会自动弹出权限申请,按指引开启后需要重启脚本/终端才能生效。
  • 目标应用必须处于运行状态,脚本会自动将应用切到前台再读取,应用处于最小化、全屏状态时可能出现部分菜单读取不全的问题,建议保持普通窗口状态运行。
  • 少数使用自定义绘制实现的非标准菜单项(未对接系统无障碍接口)无法被读取,这是应用本身的实现限制,没有通用绕过方法。

内容的提问来源于stack exchange,提问作者user43535

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 21:51:31