mac上用Automator編寫自動腳本

最近努力學習新知識,在公司內網上閱讀一些優秀文章,但是發現這些文章:是通過通過flash控件展示,並且不提供無法下載地址(類似《百度文庫》)。一次忍了,兩次再忍了,三次就無法忍受:都在我電腦上展示了,這麼做就是噁心人了。。。。
於是花了大半天時間,使用mac上自帶軟件Automator,從零開始完成了自己的工具:《連續抓圖導出PDF》。

實現原理:自動截屏、翻頁=》merge生成PDF文檔。(感興趣的人,可以下載附件看看源碼)

在寫這個腳本過程中,本以爲會很快,但是還是碰到了不少問題;於是就記錄並分享出來。

首先:最基本用法,可以直接參考Automator幫助,本文章只寫自認爲容易忽略或者難點的幾個地方。


變量使用

變量新建就不說了;這裏主要說變量再控件上使用,幾種方法(有的方法只對部分控件有用):

從下拉列表直接選擇“變量”

這裏寫圖片描述

將“變量”拖進區域

這裏寫圖片描述
當然你也可以,拋棄使用已存在的變量,直接通過下拉框選擇一個“新建變量”。

“輸入變量名”彈出提示,“回車”選擇

這裏寫圖片描述
這裏寫圖片描述

最後,如果上面三種方法你嘗試都不行的話,基本上可以宣告,那個是不支持變量的。
比如,LOOP的“次數”,是不支持變量的:
這裏寫圖片描述


腳本

腳本使用

Automator腳本支持:shell腳本(bash、perl、python、ruby等)、appleScript、javascript幾種,你可以選擇不同的腳本來運行。
這裏寫圖片描述

腳本參數傳遞

腳本和變量之間,是無法直接獲取或設置的

“變量”值傳遞到腳本

– shell腳本

        獲取到的輸入:只能是通過輸入的一行一行的字符串
        也即如果,想獲取變量值的話,可以通過,“獲得變量的值”控件來輸出值,然後傳遞到腳本然後再讀取。
        如:下面是獲取“頁數”、“URL”、“臨時文件夾”三個變量值到輸出,然後傳遞給perl腳本。

這裏寫圖片描述

– AppleScript腳本

AppleScript的輸入不是一行一行的字符串,貌似是鍵值隊(還不熟悉這塊),結果沒搞懂如何傳遞的變量——搞懂後,再補充。
於是我考慮的解決方案是:通過分隔符“|”將輸入的多行轉換成一行,然後在AppleScript進行反轉。的確是有些trick -_-!——不過後來查資料發現,也有人這麼整。

這裏寫圖片描述
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方法來了,利用上面“只會把第一行賦值給變量”的機制,通過“漏斗”方式逐個對變量進行賦值:
這裏寫圖片描述
如上圖,依次對“導出路徑”、“頁數”等多個變量進行逐個複製。
其中perl代碼作用是:過濾第一行字符串:

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

鍵盤錄製&鼠標錄製

Automator提供“錄製”功能,位於右上角:
這裏寫圖片描述
注意如果你使用錄製功能,需要mac再偏好設置裏,設置一下“允許Automator控制你的電腦”,這樣在運行時纔有用:
這裏寫圖片描述

但是實際操作起來,我碰到了下面兩個問題:

1、鼠標錄製,總是不準
2、鍵盤錄製,則永遠也沒有錄製上去

第一個問題,我沒有找到很好辦法;最後沒有使用;
第二個問題,不是錄入,而是寫代碼,通過appleScript來實現:

鍵盤操作

這裏寫圖片描述
腳本代碼是:

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.2workflow開始準備工作調用workflow1是否結束?結束yesno

注意:新建workflow1時,選擇“工組流程”:
這裏寫圖片描述

這裏實現主要有兩個問題:
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章