看例子學 Shell Programming (1) – 每日抓股價程式

自從第一個工作開始,就是以 Linux 為工作的主要內容。在嵌入式Linux系統的領域,主要的程式語言還是以C為主。但熟悉腳本語言(Script),雖不是一個必需,但卻可以讓你工作更輕鬆,更快速的完成需要的功能。甚至以往Linux的死敵 M$ Microsoft,也在 Windows 10內納入了 Ubuntu 的子系統,當然也可以執行 Shell Script,其功能之強大,完完全全是打趴 Windows Batch 。

為了衝點網誌的流量,之後將陸陸續續寫些 Shell Script 的教學文章,並且是以例子為主,說明為輔。畢竟網路上有太多 Shell Script 教學文章了,真的不缺我這一篇。我希望能透過實際的應用,展示 Shell Script 的威力用以解決生活/工作上所會碰到的實際問題。

每日股價抓取程式

下面的程式,是一個每天下午3點整,去奇摩股市抓台積電股價的程式,結果會存在檔案 “TSMC_Prices” 內。

 

行1: 指定 Shell Script 的 Interpreter 程式, 本文是用最常用的 BASH Shell

行2,3,15: 一個無限的 while loop 迴圈。行2的while條件式填1,就會達到無窮迴圈的功能。

行4: 每30秒檢查一次時間,所以就先 sleep 30,再開始檢查。

行5: 取得目前的小時和分鐘字串,這邊我們用 date 指令來取得這個資訊。date 可以自訂要輸出的時間格式,”+%H%M” 會輸出 HHMM 的時分格式,其中%H代表要取得時間,%M代表要取得分鐘。而date指令被符號 ` 包圍,是指說要執行被包圍的命令,而其輸出的內容,會被存在 now 變數內。

行6~8: 比較剛取到的目前時間,是否等於 “1500”,也就是3點。不等於的話,就會執行 continue 繼續下一個 loop (會 sleep 30秒再檢查)。行6的時間比較是用 “!=”,代表是比較字串。這邊可以注意到 != 兩邊的數字,都有用雙引號刮起來,是為了確保!=左右兩邊的內容都是字串。若只是單純的比較內容是否相同的話,一般我都會用此加雙引號的方式,可以確保即使變數內容是空,也不會導致腳本執行錯誤。

行9: 把奇摩股市的網址內容指定到一個變數,這樣程式會比較簡潔。

行10: 透過 wget 程式,將  URL 網址(也就是股價)的內容,抓下來,並存到檔案 stock.html

行11: 由於 Linux 的工具都是處理 UTF8 為主,而抓下來的網頁內容是 BIG5 編碼的,也要轉換成 UTF8 編碼才能處理。透過外部程式 iconv 工具將其轉成 UTF8 ,並存成檔案 data

行12: 此行先在剛存下的檔案 ‘data’ 找出含有 “台積電” 的行,並印出其後的5行(所以一共6行被印出)。其中收盤價是在第四行,我們利用 head 命令來取得前四行,然後再用 tail 命令取到最後一行,便可得到含有股價的那一行文字,然後將其存在 price_raw 變數。

行13: 為了只取得價格,去除其它沒用的字。我們利用 cut 指令配合 -d 參數,以特定符號為分隔,然後取出指定的欄位。一共用了兩次cut,第一次先用”<“為區隔,取得第三欄位。然後將結果再以”>”為區隔,取得第二欄位。這樣就是最後的價格了。

行14: 最後再將日期+空白+價格印出,並導向至檔案。在導入檔案時,”>>”代表檔案若不存在,則產生一個新的,若存在則加到檔尾。另外我們再一次用到date命令來取得指定的日期格式, %Y 為年份, %m 為月份, %d 為日期。

行15: 由於剛抓完股價,下次抓股價就是隔天的事了,所以我們直接sleep 86000秒(一天是86400秒),才再開始檢查。

 

可能有人會想說行12,13,我怎麼知道股價是在哪一行,在哪一個欄位。這也不是什麼秘密,就是先印出來看一看,調整一下 grep 和 cut 參數試出來的。以一般程式的寫作邏輯,每支股票的股價,應該都在同樣的相對位置上,我試了兩三支股票都是如此。當然,如果你要抓取數十支甚至數百支股票的價格,程式一定要改寫一下…不然每次都要重抓一次股票,速度慢不說,這種大量下載的用戶,搞不好會被奇摩封鎖!

Leave a Reply