自從第一個工作開始,就是以 Linux 為工作的主要內容。在嵌入式Linux系統的領域,主要的程式語言還是以C為主。但熟悉腳本語言(Script),雖不是一個必需,但卻可以讓你工作更輕鬆,更快速的完成需要的功能。甚至以往Linux的死敵
為了衝點網誌的流量,之後將陸陸續續寫些 Shell Script 的教學文章,並且是以例子為主,說明為輔。畢竟網路上有太多 Shell Script 教學文章了,真的不缺我這一篇。我希望能透過實際的應用,展示 Shell Script 的威力用以解決生活/工作上所會碰到的實際問題。
每日股價抓取程式
下面的程式,是一個每天下午3點整,去奇摩股市抓台積電股價的程式,結果會存在檔案 “TSMC_Prices” 內。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#!/bin/bash while [ 1 ] do sleep 30 now=`date +%H%M` #取得時分 if [ "$now" != "1500" ];then #每天三點才抓股價 continue fi URL="https://tw.stock.yahoo.com/s/list.php?c=%B1M%B7%7E%B4%B9%B6%EA%A5N%A4u&rr=0.33550200%201528641976" wget $URL -O stock.html #取得股價資訊 iconv -f big5 -t utf8 stock.html > data #將編碼從 BIG5 轉 UTF8 以便處理 price_raw=`grep "台積電" -A 5 data | head -n 4 | tail -n 1` #取得台積電股價所在的行 price=`echo $price_raw | cut -d'<' -f 3 | cut -d'>' -f 2` #去除其它資訊,只取價格 echo `date +%Y%m%d` " " $price >> TSMC_Prices #連同股價日期,存進檔案內 sleep 86000 done |
行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 參數試出來的。以一般程式的寫作邏輯,每支股票的股價,應該都在同樣的相對位置上,我試了兩三支股票都是如此。當然,如果你要抓取數十支甚至數百支股票的價格,程式一定要改寫一下…不然每次都要重抓一次股票,速度慢不說,這種大量下載的用戶,搞不好會被奇摩封鎖!