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

macOS下Python实现指定窗口(含后台)截图并提取文本的方法问询

在macOS下捕获指定窗口(含后台窗口)的屏幕截图并提取文本

实现思路

在macOS上捕获指定窗口(无论前台/后台、是否移动),需要借助系统原生的Quartz框架获取窗口信息并捕获截图,替换原代码中基于固定区域的截图逻辑。

依赖安装

先安装所需Python库:

pip install pyobjc-core pyobjc-framework-Quartz pytesseract schedule pillow

修改后的完整代码

import pytesseract
import schedule
import time
from Quartz import (
    CGWindowListCopyWindowInfo, kCGWindowListOptionAll, kCGNullWindowID,
    CGWindowImageCreate, kCGWindowImageBoundsIgnoreFraming,
    CFURLCreateWithFileSystemPath, kCFURLPOSIXPathStyle, kCFAllocatorDefault,
    CGImageDestinationCreateWithURL, CGImageDestinationAddImage, CGImageDestinationFinalize
)
from PIL import Image

# 配置:替换为你的目标窗口标题(或应用名称)
TARGET_WINDOW_TITLE = "Notes"  # 示例:捕获系统笔记应用窗口
output_file = 'captured_text.txt'
last_text = ""

def get_window_id_by_title(window_title):
    """根据窗口标题或应用名称查找窗口ID"""
    window_list = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID)
    for window in window_list:
        if (window_title in window.get('kCGWindowName', '') 
            or window_title in window.get('kCGWindowOwnerName', '')):
            return window['kCGWindowNumber']
    return None

def capture_window_screenshot(window_id):
    """根据窗口ID捕获截图,返回PIL图像"""
    window_image = CGWindowImageCreate(
        None, window_id, None, kCGWindowImageBoundsIgnoreFraming
    )
    if not window_image:
        return None
    
    # 将CGImage临时保存为PNG,转换为PIL图像
    temp_path = "/tmp/window_screenshot.png"
    url = CFURLCreateWithFileSystemPath(
        kCFAllocatorDefault, temp_path, kCFURLPOSIXPathStyle, False
    )
    dest = CGImageDestinationCreateWithURL(url, 'public.png', 1, None)
    CGImageDestinationAddImage(dest, window_image, None)
    CGImageDestinationFinalize(dest)
    
    return Image.open(temp_path)

def capture_and_recognize():
    global last_text

    window_id = get_window_id_by_title(TARGET_WINDOW_TITLE)
    if not window_id:
        print(f"未找到标题包含'{TARGET_WINDOW_TITLE}'的窗口")
        return
    
    screenshot = capture_window_screenshot(window_id)
    if not screenshot:
        print("窗口截图失败")
        return
    
    text = pytesseract.image_to_string(screenshot, lang='eng', config='--psm 6').strip()
    
    if text and text != last_text:
        with open(output_file, 'a') as f:
            f.write(text + '\n')
        
        print(f"Captured Text: {text}")
        last_text = text

# 调度任务(每0.5秒执行一次)
schedule.every(0.5).seconds.do(capture_and_recognize)

print("Starting text capture... Press Ctrl+C to stop.")
try:
    while True:
        schedule.run_pending()
        time.sleep(0.1)  
except KeyboardInterrupt:
    print("Text capture stopped.")

关键说明

  • 窗口匹配:代码同时支持匹配窗口标题(kCGWindowName)和应用名称(kCGWindowOwnerName),如果目标窗口无明确标题,可直接填写应用名称(如"TextEdit"、"Safari")。
  • 权限设置:macOS会要求授予屏幕录制权限,需在「系统设置 > 隐私与安全性 > 屏幕录制」中添加你的Python解释器或IDE。
  • 后台窗口支持:借助Quartz的CGWindowImageCreate API,可直接捕获后台窗口内容,无需窗口处于前台。
  • 自动适配:自动获取窗口当前位置和尺寸,窗口移动后仍能正确捕获,无需手动调整区域参数。

内容的提问来源于stack exchange,提问作者Nina W.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:50:09