之前倒騰豆瓣 API 的時(shí)候就想看看自己從標(biāo)記上「想讀」到「讀過」要花多長時(shí)間咳蔚。但我每次買書都會把看過的書的標(biāo)記刪掉,其實(shí)就是把豆瓣讀書當(dāng)作購書單搔驼。這樣的壞處就是沒法拿到「想讀」的時(shí)間了谈火。不過好在標(biāo)記「想讀」的同時(shí),豆瓣會自動幫我發(fā)一條廣播舌涨∨此#可以從廣播裏找回來。
那麼問題來了,豆瓣廣播的所有 API 操作必須登錄温技,而要登錄必須豆瓣授權(quán)革为,可是豆瓣已經(jīng)關(guān)閉授權(quán)申請了。這不「第二十二條軍規(guī)」嘛??
然後想到舵鳞,瀏覽器不有 從 cookie 嘛震檩,讓瀏覽器去抓廣播的頁面。這不就繞開了蜓堕!好了:
- 找個(gè)能操縱 GUI 的膠水把廣播頁面 down 下來抛虏;
- 找個(gè) HTML 解析庫揀出數(shù)據(jù);
- 導(dǎo)到 Excel/Numbers 之類的小型數(shù)據(jù)庫裏畫圖套才。
結(jié)果……每一步都是坑啊?? 從晚上一直幹到第二天凌晨五點(diǎn)才有些眉目迂猴。接著九點(diǎn)半又爬起來弄了會才搞定。
就像好的程序會提供「圖形界面」和「命令行」兩套接口一樣背伴,好的網(wǎng)站也會提供「服務(wù)於人的頁面」和「服務(wù)於程序」的 API 沸毁。
呃~豆瓣是個(gè)好網(wǎng)站!
先說第一步吧挂据。想用 Python 的 pyautogui 來著以清,沒裝上。然後想找找有沒有 Ruby 版的 AutoIt 崎逃。突然想到,那還不如用 Automator 或者 AppleScript 呢眉孩。又試了下 Automator 个绍,功能太簡單,轉(zhuǎn)向 AppleScript 浪汪。
AppleScript 坑
沒曾想這才是個(gè)大坑呢巴柿!連 Apple 官方的文檔都打不開。各種查資料才湊出段勉強(qiáng)能用的腳本死遭。其實(shí) AppleScript 設(shè)計(jì)得挺好的广恢,就是不知道爲(wèi)啥網(wǎng)上的資料大多沒講到點(diǎn)子上。
大家說「Mac 接口統(tǒng)一」呀潭,其實(shí)意思是「在圖形界面之外钉迷,還有一套不可見、卻能爲(wèi)程序訪問的第二界面钠署。那是機(jī)器之間的悄悄話」糠聪。是的,好程序都有兩套接口谐鼎。所以舰蟆,好程序更複雜,而不是更簡單。
在 Mac 上身害,這套「程序之間的黑話」叫「Apple events」味悄。其實(shí)任何一個(gè) Mac 程序都是一個(gè)服務(wù)器,只不過它們之間是經(jīng)由 Apple Event Manager 用 Apple events 來傳遞信息塌鸯。而 AppleScript 就是把 Apple events 包裝了下傍菇。而能聽懂這套黑話的程序叫做「AppleScriptable applications」。AppleScript 的能力邊界取決於它黏合的那些程序能幹什麼界赔。
接下來丢习,請記住:這套黑話是爲(wèi)了方便其他程序能夠理解淮悼。
就像一篇文章由段落構(gòu)成咐低,段落由句子構(gòu)成,句子由成分構(gòu)成袜腥,成分由單詞構(gòu)成见擦,單詞由字母構(gòu)成,AppleScript 是以 object 爲(wèi)單位來組織架構(gòu)的羹令。object 是包含一定信息的某種抽象鲤屡。之所以抽取出這些信息片段,是爲(wèi)了方便其他程序理解福侈。AppleScript 內(nèi)置了一些基本的 object 酒来,比如:numbers, strings, dates ...
42
3.14
"Hello, World!"
date "Friday, Sep 16, 2016"
{2, 3, 17, 18, 43, 45}
理解 AppleScript 的關(guān)鍵之一,就是弄清楚程序是怎麼來組織信息的肪凛,這些信息單元又對應(yīng)於哪些 objects堰汉,可以通過哪些 commands 來操作這些 objects 。
之前接觸 AppleScript 的時(shí)候伟墙,之所以覺得一地雞毛翘鸭、零碎得很的原因就在於沒有弄清楚操作對象的 objects 組織架構(gòu)(也就是 objets model)。
有三種方法可以操控 object 戳葵,分別是:command, operactor, variable.
而把這些黏合起來的就乓,就是「控制語句」:
- 我該不該做這個(gè)? Should I do this?
- 我該做多少次拱烁? How often should I do this?
- 要是出錯了怎麼辦生蚁? What should I do if things go wrong?
以及某種抽象機(jī)制——handlers[1] & script objects.
神奇的是,AppleScript 的 handlers 允許先調(diào)用邻梆,後定義[2]?? 但不允許嵌套定義守伸。
但,最最神奇的是浦妄,AppleScript 允許一套通過標(biāo)籤(而非位置)來傳遞參數(shù)的方式定義 handler 尼摹。既可以是預(yù)定義的標(biāo)籤[^predefined label]见芹,也可以是自定義標(biāo)籤[^user label]。這才是 AppleScript 敢把自己叫做「English-like」語言的原因蠢涝。
[^predefined label]: predefined labels 有23個(gè):about
, above
, against
, apart from
, around
, aside from
, at
, below
, beneath
, beside
, between
, by
, for
, from
, instead of
, into
, on
, onto
, out of
, over
, since
, thru
(or through
), and under
. 另外玄呛,第一個(gè)參數(shù)可以用in
或of
來標(biāo)識,但僅限於第一個(gè)參數(shù)和二。
[^user label]: user labels 用given
來標(biāo)識徘铝。如果自定義標(biāo)籤所指示的參數(shù)是 boolean 變量,在調(diào)用時(shí)可以用with
來設(shè)置爲(wèi)true
惯吕,或者用without
來設(shè)置爲(wèi)false
惕它。
用腳本去操控程序,根本就不是去模擬人的點(diǎn)擊废登、鍵入……淹魄,而是腳本直接與程序?qū)υ挕ppleScript 中類似「點(diǎn)擊」「鍵入」……等動作的操作堡距,就是 commands 甲锡。
所有的程序會響應(yīng) run, open, quit 這些指令。有的程序還會提供自己的特有指令羽戒。人缤沦,是通過點(diǎn)擊 menus, buttons 這些圖形元素來操縱程序。而程序通過 commands 來操控其他程序易稠。既然是指令缸废,就需要有作用對象。這樣缩多,commands 就和 objects 綁定起來了呆奕。
nokogiri 坑
……