使用AppleScript提取图片文本粘贴至Google Sheet偶发失败求助
问题排查:AppleScript粘贴到Google Sheet时有时失败
你的核心问题是OCR提取文本到剪贴板正常,但模拟Cmd+V粘贴到Chrome中的Google Sheet时不稳定,主要原因在于窗口/标签的焦点控制不可靠、固定延迟的不确定性,以及未处理标签未找到的异常情况,以下是具体排查点和修复方案:
1. 未处理「未找到目标标签」的异常
当前代码中如果没有标题包含SheetTitle的标签,GoogleTab变量会未定义,后续执行set active tab index会报错,直接导致粘贴失败。
修复方案:先初始化GoogleTab为无效值,找到标签后再赋值,最后检查是否找到目标标签:
set GoogleTab to 0 -- 初始化无效值 tell application "Google Chrome" repeat with w in windows set i to 1 repeat with t in tabs of w if title of t contains the SheetTitle then set active tab index of w to i set index of w to 1 set GoogleTab to i exit repeat -- 找到后退出内层循环 end if set i to i + 1 end repeat if GoogleTab ≠ 0 then exit repeat -- 找到后退出外层循环 end repeat end tell -- 检查是否找到目标标签 if GoogleTab = 0 then display alert "未找到目标表格标签" return end if
2. 模拟按键粘贴的焦点问题
即使切换到目标标签,Chrome可能还没完成页面加载,或者Sheet的编辑单元格未获得焦点,直接按Cmd+V会无效。
更可靠的方案:用JavaScript直接插入文本
避免模拟系统按键,而是通过Chrome的execute javascript接口直接将文本写入当前激活的单元格,稳定性大幅提升:
set extractedText to getImageText(theFile) as text tell application "Google Chrome" activate set the active tab index of the front window to GoogleTab -- 等待页面就绪(替代固定delay) repeat until (loading of active tab of front window is false) delay 0.5 end repeat -- 执行JS将文本插入当前选中的单元格 execute javascript "document.activeElement.value = '" & escapedText(extractedText) & "';" end tell -- 辅助函数:转义JS字符串中的特殊字符 on escapedText(txt) set AppleScript's text item delimiters to "\\" set txt to text items of txt set AppleScript's text item delimiters to "\\\\" set txt to txt as string set AppleScript's text item delimiters to "\"" set txt to text items of txt set AppleScript's text item delimiters to "\\\"" set txt to txt as string set AppleScript's text item delimiters to return set txt to text items of txt set AppleScript's text item delimiters to "\\n" set txt to txt as string return txt end escapedText
3. 固定延迟的不确定性
固定delay 3完全依赖系统性能,负载高时延迟不够,负载低时浪费时间,且无法保证操作同步。
修复方案:替换为条件等待
比如等待Chrome窗口激活、等待标签加载完成:
tell application "Google Chrome" activate -- 等待Chrome成为前台应用 repeat until frontmost of application "Google Chrome" is true delay 0.2 end repeat set the active tab index of the front window to GoogleTab -- 等待标签加载完成 repeat until (loading of active tab of front window is false) delay 0.5 end repeat end tell
4. 剪贴板设置的优化(可选)
虽然你验证了剪贴板内容正常,但用AppleScript原生set the clipboard有时会出现格式兼容问题,改用AppKit的NSClipboard设置纯文本更可靠:
set extractedText to getImageText(theFile) as text set thePasteboard to current application's NSPasteboard's generalPasteboard() thePasteboard's clearContents() thePasteboard's setString:extractedText forType:(current application's NSPasteboardTypeString)
完整修复后的代码示例
整合以上所有优化点,最终代码如下:
set SheetTitle to "Stuff I Need" use framework "AppKit" use framework "Foundation" use framework "Vision" use scripting additions on getImageText(imagePath) -- Get image content set theImage to current application's NSImage's alloc()'s initWithContentsOfFile:imagePath -- Set up request handler using image's raw data set requestHandler to current application's VNImageRequestHandler's alloc()'s initWithData:(theImage's TIFFRepresentation()) options:(current application's NSDictionary's alloc()'s init()) -- Initialize text request set theRequest to current application's VNRecognizeTextRequest's alloc()'s init() -- Perform the request and get the results requestHandler's performRequests:(current application's NSArray's arrayWithObject:(theRequest)) |error|:(missing value) set theResults to theRequest's results() set theArray to current application's NSMutableArray's new() repeat with aResult in theResults (theArray's addObject:(((aResult's topCandidates:1)'s objectAtIndex:0)'s |string|())) end repeat return (theArray's componentsJoinedByString:linefeed) as text -- return a string end getImageText -- 查找目标Google Sheet标签 set GoogleTab to 0 tell application "Google Chrome" repeat with w in windows set i to 1 repeat with t in tabs of w if title of t contains the SheetTitle then set active tab index of w to i set index of w to 1 set GoogleTab to i exit repeat end if set i to i + 1 end repeat if GoogleTab ≠ 0 then exit repeat end repeat end tell -- 检查是否找到标签 if GoogleTab = 0 then display alert "错误" message "未找到标题包含「" & SheetTitle & "」的标签" return end if set theFile to POSIX path of "/Users/[yourname]/Desktop/Screenshots/Screen-01.jpeg" set extractedText to getImageText(theFile) as text -- 优化剪贴板设置(可选,若使用JS插入则可省略) -- set thePasteboard to current application's NSPasteboard's generalPasteboard() -- thePasteboard's clearContents() -- thePasteboard's setString:extractedText forType:(current application's NSPasteboardTypeString) -- 激活Chrome并插入文本 tell application "Google Chrome" activate repeat until frontmost is true delay 0.2 end repeat set the active tab index of the front window to GoogleTab repeat until (loading of active tab of front window is false) delay 0.5 end repeat -- 执行JS插入文本到当前激活单元格 execute javascript "document.activeElement.value = '" & escapedText(extractedText) & "';" end tell -- 转义JS特殊字符的辅助函数 on escapedText(txt) set AppleScript's text item delimiters to "\\" set txt to text items of txt set AppleScript's text item delimiters to "\\\\" set txt to txt as string set AppleScript's text item delimiters to "\"" set txt to text items of txt set AppleScript's text item delimiters to "\\\"" set txt to txt as string set AppleScript's text item delimiters to return set txt to text items of txt set AppleScript's text item delimiters to "\\n" set txt to txt as string return txt end escapedText
内容的提问来源于stack exchange,提问作者Cleveburgian
相关产品推荐
相关产品推荐

