# Automator 手册第六章：在 Automator 中使用 Python

> 本文公开全文。

原文：https://utgd.net/article/20225

不论如何，如果相比其他的脚本语言，你更喜欢或更擅长 Python 的话，这一章番外篇就是为你准备的。暂时用不上 Python 的读者也不用丧气，本系列文章原计划中没有这部分内容，所以权当作附赠的吧。

## 为什么要用 Python

介绍 Python，当然不仅仅是因为“有读者需要”，毕竟这门语言若是用得上的人寥寥无几，我可能私下就回复掉，而不至于特意写一篇文章了。

Python 是数据处理的利器。工科、理科、乃至很多完全没有编程背景的文科人士，都有用 Python 来处理数据的需求。

熟悉效率工具的读者，对 Python 应该也不陌生。

那么，在 Automator 中如何使用 Python 这一利器？出于通用性考虑，我将提供 Python2\.7 和 Python3 两套模板（既然能坚持读到这里，相信你懂的，有些学校/公司至今抱着 2\.7 版本不撒手），即便你并没有太专业的编程知识，也可以查一下自己在用的 Python 版本，然后套上模板完事儿。

## 两个基础模板

下面是 Python2/7 和 Python3 两种模板。

- Python2\.7

- Python3

### Python 2\.7

2\.7 版本的模板相对简单，和 Shell 脚本章节的设置非常相似：

- Shell 设置为 /usr/bin/python

- 输入作为 stdin

- 脚本模板间下方：

```
#!/usr/bin/env python

mport sys
#你的其他模块

or f in sys.stdin:
    #你的脚本
```

在这个模板里，环境变量、文件输入、批处理之类的都帮你收拾好了。不过 Python 有一点比较特殊，就是需要导入各种功能模块，所以把你的脚本搬进模板时也不要忘记把模块装上。

### Python 3

想要在 Automator 直接使用 Python3 就麻烦了。一般我们在脚本编辑器里写 Python 代码时，只需要在开头申明一下环境变量就能调用 Python3，可惜在 Automator 里这不奏效。不信邪的话，你可以试试强制指定使用 Python3：

很不幸，最后你发现拿在手里的还是 Python2\.7。这是因为，我们已经指定了 Shell 为 /usr/bin/python，脚本里写啥都于事无补。所以换个思路，不用 /usr/bin/python，直接通过 bash 调用 Python3 怎么样？

- 将 Shell 设置为 /bin/bash

- 将输入设为作为自变量

- 脚本如下：

```
runpy3 () {
/usr/local/bin/python3 << 'EOF' - "$@"

import sys
#你的其他模块

for f in sys.argv:
    #你的脚本
EOF
}

runpy3 "$@"
```

再来测试一下，终于看见 Python3 了。接下来的事儿交给你，把自己的脚本填进去吧。

## 如何查看 Python 的运行结果

和使用 AppleScript/Shell 脚本时一样，我们也希望能看到 Python 的运行结果，而不是瞪着一只黑箱乞求它运行成功。最合适的方法还是在系统通知里显示运行的结果或状态提示。

我们照例来看两个例子，一个使用 Automator 自带的模块，一个利用 Python 脚本，简单和详细的要求都能满足。

简单版的大家都再熟悉不过了（如果你读过前两章的话），老规矩套上通知模块：

进阶一些，还是用脚本。脚本方案实质上还是在借用 AppleScript，所以之前学的 macOS 通知模板知识照样能用。下面提供的模板已经解决了零零碎碎的工作，你只需要套用进自己的 Automator 动作，然后自定义两个地方：

- 这里是通知内容：填进自己通知标题。可以把整行 "这里是通知内容" 换成脚本中出现的变量，具体的各位 Python 玩家请自行组合。

- 这里是通知信息：填进通知信息。同样可以使用变量。

```
from subprocess import call

noti_title = "这里是通知内容"
noti_msg = "这里是通知信息"
noti_cmd = 'display notification \"' + \
    noti_msg + '\" with title \"' + noti_title +'\"'

call(["osascript", "-e", noti_cmd])
```

搞定。

## 实战：做一个 JSON 美化工具

说到 Python 脚本最适合的使用场景，可能 JSON 数据的处理就是第一个。

先别急着关网页，其实玩过 iOS 自动化的读者，多多少少都接触过 JSON——捷径里面常见的扒网页动作，往往就要出来网页返回来的，什么豆瓣电影数据、图片地址、视频网址都藏在里面。为什么要用“藏”这个说法呢？看看捷径返回来的 JSON 数据你就知道了。

这样的数据看起来当然不方便，于是有人开发了一些网页版 JSON 格式化工具。其实也有离线使用的办法，马上来看看 Automator 是怎么解决的。

这回我们在 Automator 里使用 Python 2\.7，Shell 选择 /usr/bin/python，传递输入作为自变量，脚本在配图之后奉上。

```
import os
import sys
import json
from subprocess import call
from subprocess import Popen, PIPE

noti_title_error = "json parse error."
noti_title_nojson = "argv's length is 1, no json text input."
noti_msg_error = "请输入合法的 JSON"
noti_msg_nojson = "你输入的啥都不是啊！"
noti_cmd_error = 'display notification \"' + \
    noti_msg_error + '\" with title \"' + noti_title_error +'\"'
noti_cmd_nojson = 'display notification \"' + \
    noti_msg_nojson + '\" with title \"' + noti_title_nojson +'\"'

length = len(sys.argv)

if length > 1:
    try:
        cmd = 'curl -s '+str(sys.argv[1])
        search_result = os.popen(cmd)
        jsonObj = json.loads(search_result.read())
        formatJsonStr = json.dumps(jsonObj,indent=4,ensure_ascii=False,sort_keys=True)

        scpt = '''
            on run {clipboard_content}
                tell application "System Events"
                    set activeApp to name of first application process whose frontmost is true
                    activate
                    display dialog the ["JSON Formatted! Copy to clipboard? \n\n" & clipboard_content] buttons {"Copy", "No Thanks"} default button 1 cancel button 2
                end tell

                set result_button to button returned of result as string

                if result_button is "Copy" then
                    set the clipboard to clipboard_content

                end if
            end run'''
        args = [formatJsonStr]

        p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
        p.communicate(scpt)
    except Exception, e:
        call(["osascript", "-e", noti_cmd_error])
else :
    call(["osascript", "-e", noti_cmd_nojson])
```

运行时填入想要捣鼓的网页，Automator 就会弹出格式化好的 JSON 结果（如果太长的话可能会在屏幕上顶天立地）并询问你要不要拷贝到剪贴板。

JSON 数据处理只是 Python 的各项特长之一，其他玩法还是留给更专业的玩家吧。

---

[前往标准阅读页](https://utgd.net/article/20225?audience=web)
