2019年2月7日 星期四

網頁畫面定時快照截圖

過年期間的天氣圖 想要定期下載某網頁, 可以在 cron job 裡面用 wget。 [ 鳥哥 教育大市集] 但這僅適用於伺服器端產生的靜態網頁。 如果是 javascript 產生的動態網頁呢? 如果需要取得網頁文字內容, 那就必須用比較進階的 網頁爬蟲終極武器: puppeteer; 如果只需要快照截圖 (例如想要觀察 google 地圖或開放街圖某塊區域的長期變化), 那麼本篇介紹的 cutycapt 就夠用了。

從命令列上抓 (靜態的或 javascript 所動態產生的) 網頁畫面快照截圖, 可以這樣做: cutycapt --url=https://www.openstreetmap.org/#map=17/24.06870/120.71315 --out=cyut.jpg 有些網站需要花比較多的時間執行 javascript 填入畫面元素, 那就加上 --delay=3000 之類的選項, 延遲個 3 秒鐘, 等它畫好再拍照。 先前改作業時需要手動點進幾十個 osm 網址、 再加上幾十次「回上一頁」, 覺得很煩。 改用這種方式截圖, 搭配 for 迴圈, 省下了等待網頁的時間及一半的按鍵。

但是想把它放進 crontab 會失敗, 因為 cutycapt 執行的時候需要視窗環境。 事實上不必用 cron 測試; 按 ctrl-alt-f1 切到文字終端機就會發現上述指令會失敗。 這時可以安裝 xvfb 套件, 然後改成這樣下指令: xvfb-run --server-args="-screen 0, 1024x768x24" cutycapt --url=https://www.openstreetmap.org/#map=17/24.06870/120.71315 --out=a.jpg 詳見 cutycapt 官網

地圖短時間內沒什麼變化, 太無聊了。 改拿中央氣象局的 地面天氣圖 來做實驗。 在 24x7 不關機的伺服器上, 先 mkdir ~/weather 然後用 crontab -e 叫出編輯畫面。 (如果你不會用 vim, 可以趁這個機會 學 vim; 或是你可能需要 逃離 vim) 加入下面這列:

28 2,8,14,20 * * * /home/ckhung/.../weather.sh > /dev/null

意思是每天的 2:28、 8:28、 14:28、 20:28 四次執行 weather.sh , 不要寄 mail 通知。 其中 weather.sh 的內容如下:

#!/bin/bash
xvfb-run --server-args="-screen 0, 1024x768x24" cutycapt --url=https://www.cwb.gov.tw/V7/forecast/fcst/I05.htm --out=/tmp/cutycapt.png
convert -auto-orient -quality 80 -interlace line /tmp/cutycapt.png $HOME/weather/$(date '+%m%d%H').jpg

抓回來的圖可以用 convert 020310.jpg -stroke red -fill none -strokewidth 3 -draw 'line 178 193 915 735' a.jpg 之類的指令測試, 不斷地改變座標、 查看 a.jpg , 直到紅線恰好從圖片的左上畫到右下為止。 然後計算 915-178=737、 735-193=542 於是就可以用 for f in 02*.jpg ; do convert $f -crop 737x542+178+193 /tmp/$f ; done 裁剪、 用 convert -delay 100 /tmp/02*.jpg ~/weather.gif 把所有圖片合併成 gif 動畫。

這個例子其實有點殺雞用牛刀, 脫褲子放屁 -- 它的圖片只是一個靜態的檔案, 而且網址很有規律, 所以根本不需要用 crontab, 可以直接一口氣 wget 許多歷史圖檔。 可是文人都要為賦新辭強說愁, 我也不能免俗。

沒有留言:

張貼留言