mac上用Automator编写自动脚本

  • 变量使用
    • 从下拉列表直接选择变量
    • 将变量拖进区域
    • 输入变量名弹出提示回车选择
  • 脚本
    • 脚本使用
    • 脚本参数传递
      • 变量值传递到脚本
      • 脚本结果设置到变量中
  • 键盘录制鼠标录制
    • 键盘操作
      • 普通字符
      • 特殊字符
      • 组合键
  • 循环
    • 简单循环
    • 复杂循环
    • 附1-key code 表
    • 附1-连续抓图导出PDF脚本

最近努力学习新知识,在公司内网上阅读一些优秀文章,但是发现这些文章:是通过通过flash控件展示,并且不提供无法下载地址(类似《百度文库》)。一次忍了,两次再忍了,三次就无法忍受:都在我电脑上展示了,这么做就是恶心人了。。。。
于是花了大半天时间,使用mac上自带软件Automator,从零开始完成了自己的工具:《连续抓图导出PDF》。

实现原理:自动截屏、翻页=》merge生成PDF文档。(感兴趣的人,可以下载附件看看源码)

在写这个脚本过程中,本以为会很快,但是还是碰到了不少问题;于是就记录并分享出来。

首先:最基本用法,可以直接参考Automator帮助,本文章只写自认为容易忽略或者难点的几个地方。


变量使用

变量新建就不说了;这里主要说变量再控件上使用,几种方法(有的方法只对部分控件有用):

从下拉列表直接选择“变量”

mac上用Automator编写自动脚本_第1张图片

将“变量”拖进区域

mac上用Automator编写自动脚本_第2张图片
当然你也可以,抛弃使用已存在的变量,直接通过下拉框选择一个“新建变量”。

“输入变量名”弹出提示,“回车”选择

mac上用Automator编写自动脚本_第3张图片
mac上用Automator编写自动脚本_第4张图片

最后,如果上面三种方法你尝试都不行的话,基本上可以宣告,那个是不支持变量的。
比如,LOOP的“次数”,是不支持变量的:
mac上用Automator编写自动脚本_第5张图片


脚本

脚本使用

Automator脚本支持:shell脚本(bash、perl、python、ruby等)、appleScript、javascript几种,你可以选择不同的脚本来运行。
mac上用Automator编写自动脚本_第6张图片

脚本参数传递

脚本和变量之间,是无法直接获取或设置的

“变量”值传递到脚本

– shell脚本

        获取到的输入:只能是通过输入的一行一行的字符串
        也即如果,想获取变量值的话,可以通过,“获得变量的值”控件来输出值,然后传递到脚本然后再读取。
        如:下面是获取“页数”、“URL”、“临时文件夹”三个变量值到输出,然后传递给perl脚本。

mac上用Automator编写自动脚本_第7张图片

– AppleScript脚本

AppleScript的输入不是一行一行的字符串,貌似是键值队(还不熟悉这块),结果没搞懂如何传递的变量——搞懂后,再补充。
于是我考虑的解决方案是:通过分隔符“|”将输入的多行转换成一行,然后在AppleScript进行反转。的确是有些trick -_-!——不过后来查资料发现,也有人这么整。

mac上用Automator编写自动脚本_第8张图片
perl代码:

@input = ();
while (<>) {
        $_=~s/(^\s*)|(\s*$)//g;
        push(@input,$_);
}
print join "|" ,@input;

AppleScript代码:

on run input

    set myArray to my theSplit((item 1 of input) as string, "|")
    set outputPath to item 1 of myArray
    set pagenum to item 2 of myArray as number
    set myurl to item 3 of myArray
    set tempDir to item 4 of myArray

    return myArray
end run

on theSplit(theString, theDelimiter)
    -- save delimiters to restore old settings
    set oldDelimiters to AppleScript's text item delimiters

    -- set delimiters to delimiter to be used
    set AppleScript's text item delimiters to theDelimiter

    -- create the array
    --set theArray to every text item of theString
    set theArray to text items of theString

    -- restore the old setting
    set AppleScript's text item delimiters to oldDelimiters

    -- return the result
    return theArray
end theSplit

脚本结果,设置到“变量”中

脚本中的变量,是无法设置到脚本中,怎么办呢?其也只能通过脚本输出结果,然后“设定变量的值”控件,对变量进行设置。
- - 设置一个变量

这里写图片描述

注意:这里有一个问题,如果脚本输出的是多行,其实只把第一行字符串,赋值到“变量”中

    • 设置多个变量

但是如果要设置多个变量值,咋办?
于是又是一个trick方法来了,利用上面“只会把第一行赋值给变量”的机制,通过“漏斗”方式逐个对变量进行赋值:
mac上用Automator编写自动脚本_第9张图片
如上图,依次对“导出路径”、“页数”等多个变量进行逐个复制。
其中perl代码作用是:过滤第一行字符串:

$count=0;
while(<>){
    print $_ if $count >0 ; 
    $count = $count + 1 ;
}

键盘录制&鼠标录制

Automator提供“录制”功能,位于右上角:
mac上用Automator编写自动脚本_第10张图片
注意如果你使用录制功能,需要mac再偏好设置里,设置一下“允许Automator控制你的电脑”,这样在运行时才有用:
mac上用Automator编写自动脚本_第11张图片

但是实际操作起来,我碰到了下面两个问题:

1、鼠标录制,总是不准
2、键盘录制,则永远也没有录制上去

第一个问题,我没有找到很好办法;最后没有使用;
第二个问题,不是录入,而是写代码,通过appleScript来实现:

键盘操作

mac上用Automator编写自动脚本_第12张图片
脚本代码是:

on run {input, parameters}
    -- 
    set timeoutSeconds to 0
    set uiScript to "keystroke \"a\" " --标注,注意这行代码
    my doWithTimeout(uiScript, timeoutSeconds)
    return input
end run

on doWithTimeout(uiScript, timeoutSeconds)
    set endDate to (current date) + timeoutSeconds
    repeat
        try
            run script "tell application \"System Events\"
" & uiScript & "
end tell"
            exit repeat
        on error errorMessage
            if ((current date) > endDate) then
                error "Can not " & uiScript
            end if
        end try
    end repeat
end doWithTimeout

接下来,看看键盘操作(均是修改,标注的那一行)几种情况解决方案:

普通字符

普通字符,比较简单,使用keystroke ,输入字符就可以,比如输入”a”字符:

set uiScript to "keystroke \"a\" "

特殊字符

对于一些特殊字符,没有特殊ASCII码,比如:上、下、左、右键。因此可以考虑另外一个通过“键值”(即操作系统对按键的虚拟值)来实现,key code :

比如:“右”按键的代码是:

set uiScript to "key code 124  "

当然,key code 也可以输入普通字符,如:
“a” 按键代码是:

set uiScript to "key code 0  "

“A”按键代码是:

set uiScript to "key code 0  using {shift down} "

mac系统的虚拟键值,可以通过终端命令执行下面命令查询到:

$ grep '^ *kVK' /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h|tr -d ,|while read x y z;do printf '%d %s %s\n' $z $z ${x#kVK_};done|sort -n

或者你直接查下“附1-key code 表”也行:

组合键

上两个方法,都可以配合组合键进行使用:

set uiScript to "key code 124 using {control down, option down, command down,shift down}" --control+option+command+right+shift

循环

Automator对于系列处理动作的流程,制作非常简单,仅仅需要拖拽基本就可以实现。
但是在分支、循环等这种逻辑上,处理起来要复杂很多。 基本稍微复杂一点的都需要脚本配合才可以的。

简单循环

Automator只提供了简单的“Loop”循环控件,这个循环控件可控执行很差,因为:

  • 只能从脚本开头循环

  • 循环策略支持:
    A)次数/时间,但是无法通过变量控制
    B)询问方式
    试想一下,你就是需要从中间块循环,但是他非要从开头开始,你是无法选择的,这是个多么想哭的事情。

复杂循环

那么对于复杂的循环怎么处理?
Automator支持workflow的调用,因此如果你需要循环的话一种解决方案就是:将需要循环块的部分,写成workflow1,然后再主workflow通过脚本控制workflow1的循环。

Created with Raphaël 2.1.2 workflow开始 准备工作 调用workflow1 是否结束? 结束 yes no

注意:新建workflow1时,选择“工组流程”:
mac上用Automator编写自动脚本_第13张图片

这里实现主要有两个问题:
1、workflow之间的变量是无法共享的(至少现在我发现是这样的)。它也只能想字符串一样传递。
但是这个问题:上面脚本使用一节中的“多变量的赋值”方法可以解决。

2、如何脚本调用,workflow?
通过 do shell script cmd,进行执行cmd命令调用,但是这里有一个问题就是:命令执行是不等待结束立即返回的(实现方法是新起进程执行)——目前还没有找到能够等待返回的方法。

on run input

    set myArray to my theSplit((item 1 of input) as string, "|")
    set outputPath to item 1 of myArray
    set pagenum to item 2 of myArray as number
    set myurl to item 3 of myArray
    set tempDir to item 4 of myArray

    delay 10
    set mycount to 1000 as number
    repeat
        run_workflow(tempDir & "/" & (mycount) & ".pdf", "/Users/xxxx/Desktop/test2/自动截频.workflow")
        if pagenum ≤ 1 then
            exit repeat
        end if
        set pagenum to pagenum - 1
        set mycount to mycount + 1

        --按下右键
        set timeoutSeconds to 2
        set uiScript to "keystroke (ASCII character 29)  "
        my doWithTimeout(uiScript, timeoutSeconds)
    end repeat
    delay 1
    return myArray
end run

--执行workflow
on run_workflow(inputVars, workflowPath)
    set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, linefeed}
    set theInputsList to inputVars as text
    set AppleScript's text item delimiters to tid
    set cmd to "automator -i '" & theInputsList & "' " & workflowPath
    return do shell script cmd
end run_workflow

on theSplit(theString, theDelimiter)
    -- save delimiters to restore old settings
    set oldDelimiters to AppleScript's text item delimiters

    -- set delimiters to delimiter to be used
    set AppleScript's text item delimiters to theDelimiter

    -- create the array
    --set theArray to every text item of theString
    set theArray to text items of theString

    -- restore the old setting
    set AppleScript's text item delimiters to oldDelimiters

    -- return the result
    return theArray
end theSplit

on doWithTimeout(uiScript, timeoutSeconds)
    set endDate to (current date) + timeoutSeconds
    repeat
        try
            run script "tell application \"System Events\"
" & uiScript & "
end tell"
            exit repeat
        on error errorMessage
            if ((current date) > endDate) then
                error "Can not " & uiScript
            end if
        end try
    end repeat
end doWithTimeout

附1-key code 表

十进制 十六进制 按键
0 0x00 ANSI_A
1 0x01 ANSI_S
2 0x02 ANSI_D
3 0x03 ANSI_F
4 0x04 ANSI_H
5 0x05 ANSI_G
6 0x06 ANSI_Z
7 0x07 ANSI_X
8 0x08 ANSI_C
9 0x09 ANSI_V
10 0x0A ISO_Section
11 0x0B ANSI_B
12 0x0C ANSI_Q
13 0x0D ANSI_W
14 0x0E ANSI_E
15 0x0F ANSI_R
16 0x10 ANSI_Y
17 0x11 ANSI_T
18 0x12 ANSI_1
19 0x13 ANSI_2
20 0x14 ANSI_3
21 0x15 ANSI_4
22 0x16 ANSI_6
23 0x17 ANSI_5
24 0x18 ANSI_Equal
25 0x19 ANSI_9
26 0x1A ANSI_7
27 0x1B ANSI_Minus
28 0x1C ANSI_8
29 0x1D ANSI_0
30 0x1E ANSI_RightBracket
31 0x1F ANSI_O
32 0x20 ANSI_U
33 0x21 ANSI_LeftBracket
34 0x22 ANSI_I
35 0x23 ANSI_P
36 0x24 Return
37 0x25 ANSI_L
38 0x26 ANSI_J
39 0x27 ANSI_Quote
40 0x28 ANSI_K
41 0x29 ANSI_Semicolon
42 0x2A ANSI_Backslash
43 0x2B ANSI_Comma
44 0x2C ANSI_Slash
45 0x2D ANSI_N
46 0x2E ANSI_M
47 0x2F ANSI_Period
48 0x30 Tab
49 0x31 Space
50 0x32 ANSI_Grave
51 0x33 Delete
53 0x35 Escape
55 0x37 Command
56 0x38 Shift
57 0x39 CapsLock
58 0x3A Option
59 0x3B Control
60 0x3C RightShift
61 0x3D RightOption
62 0x3E RightControl
63 0x3F Function
64 0x40 F17
65 0x41 ANSI_KeypadDecimal
67 0x43 ANSI_KeypadMultiply
69 0x45 ANSI_KeypadPlus
71 0x47 ANSI_KeypadClear
72 0x48 VolumeUp
73 0x49 VolumeDown
74 0x4A Mute
75 0x4B ANSI_KeypadDivide
76 0x4C ANSI_KeypadEnter
78 0x4E ANSI_KeypadMinus
79 0x4F F18
80 0x50 F19
81 0x51 ANSI_KeypadEquals
82 0x52 ANSI_Keypad0
83 0x53 ANSI_Keypad1
84 0x54 ANSI_Keypad2
85 0x55 ANSI_Keypad3
86 0x56 ANSI_Keypad4
87 0x57 ANSI_Keypad5
88 0x58 ANSI_Keypad6
89 0x59 ANSI_Keypad7
90 0x5A F20
91 0x5B ANSI_Keypad8
92 0x5C ANSI_Keypad9
93 0x5D JIS_Yen
94 0x5E JIS_Underscore
95 0x5F JIS_KeypadComma
96 0x60 F5
97 0x61 F6
98 0x62 F7
99 0x63 F3
100 0x64 F8
101 0x65 F9
102 0x66 JIS_Eisu
103 0x67 F11
104 0x68 JIS_Kana
105 0x69 F13
106 0x6A F16
107 0x6B F14
109 0x6D F10
111 0x6F F12
113 0x71 F15
114 0x72 Help
115 0x73 Home
116 0x74 PageUp
117 0x75 ForwardDelete
118 0x76 F4
119 0x77 End
120 0x78 F2
121 0x79 PageDown
122 0x7A F1
123 0x7B LeftArrow
124 0x7C RightArrow
125 0x7D DownArrow
126 0x7E UpArrow

附1-《连续抓图导出PDF》脚本

http://download.csdn.net/detail/destiny_ac/8461453

你可能感兴趣的:(automator,自动脚本)