2020/01/29

[自己的 Hackathon] L10 盃黑客松之即時開票系統 - 技術分享 (二) - 學習 Google Sheet API 與 Crawler

在上一篇依著微軟官方教學文件
學會了利用 Visual Studio Code 建立以及發佈 Azure Functions
接著就是要寫出我想要的 Crawler 以及即時更新 Google spreadsheet 的功能

流程簡圖

建立測試 Endpoint 來做 POC


因為每個部份我都沒有實際自己寫過
所以方便起見我建立了一個 HTTP trigger 的 Azure Function
在裡面寫一些 POC 的小片段
再把可行的部分搬移到對應的 Crawler 或是 Update Handler 中
我簡單盤點了一下我需要完成的幾項工作

T1. 從中選會網頁上爬到票數
T2. 將票數轉換成我定義好的 JSON 後,塞入 Azure Queue Storage 中
T3. 從 Azure Queue Storage 取出 JSON
T4. 依 JSON 中的對應票數,使用 Google Sheet API 填入 Google spreadsheet 對應的格子中

首先很快的利用 Azure Functions extension 建立好三個 Azure Functions
分別為

1. Timer trigger 的 Crawler
2. Azure Queue Storage trigger 的 Update Handler
3. HTTP trigger 的測試 Azure Function

最先完成的就是最簡單的 T2 與 T3
因為在教學文件中都有介紹到
唯一不同的就是要設計自己的 JSON 樣子而已
{
  "time": "1580121166",
  "votes" : {
    "president" : { "blue" : 1, "green" : 1 },
    "taipei3" : { "blue" : 1, "green" : 1 },
    "taipei4" : { "blue" : 1, "green" : 1 },
    "taipei5" : { "blue" : 1, "green" : 1 },
    "taichung3" : { "blue" : 1, "green" : 1 },
    "hualien" : { "blue" : 1, "green" : 1 }
  }
}


使用 Google Sheet API 填入對應票數


將 Crawler 與 Update Handler 串起後
下一件事情是學習怎麼在 Update Handler 中
用 Google Sheet API 去更新 spreadsheet
我是使用 pygsheets 這個 package
說明文件也算清楚
可以在 requirements.txt 中填入要使用的其他套件
在執行 debugger 的時候會自動用 pip install 幫你安裝

使用 pygsheets 套件前得先取得 Google API 的授權
我是使用 Service Account 的方法
要注意的就是 credentials.json 的檔案位置
一開始一直傳不對的路徑進去
導致卡關了一小段時間

學習怎麼寫 Crawler


我主要是看這個影片
[爬蟲實戰] 如何透過 Python 網路爬蟲 抓取並整理 2018 公投選舉資料?
非常仔細也非常詳盡
裡面介紹了兩個 packages, BeautifulSoup 與 pandas
我只需要用到 pandas 就好
就先用候選人簡歷的頁面練習
原則上是沒有遇到太大的問題
有錯誤的時候稍微再到 pandas 的官網查一下文件
或是利用 Google 都可以找到解答

利用條件式格式設定 highlight 第一名


我本來就會使用 RANK() 這個函式來排名
這次有兩個題目的排序需要預先處理,再餵入 RANK()
又很自以為的不想使用輔助欄 (就是先在其他格子內算出結果)
沒想到也搞了很久

ARRAYFORMULA() 應用


第一個是我要依 "絕對值" 由小到大排名
在這裡學到的一個公式是 ARRAYFORMULA()
ARRAYFORMULA() 可以想成本來 ABS() 這個函式只能計算一個格子的絕對值
套用 ARRAYFORMULA() 後,我們可以計算一個範圍內所有格子個別的絕對值
因此我們可以使用 ARRAYFORMULA() 的結果
再傳入 RANK() 的第二參數裡面使用
這樣我就不必使用一個輔助欄來先行計算絕對值再套用 RANK() 函式了

ARRAYFORMULA() 的結果


第二個是我要依 Max( |∆KMT|, |∆DPP| ) 由小到大排名
上圖中可以看到我用 ARRAYFORMULA() 先取得了一個二維的絕對值結果
下一步我需要把結果套入一個公式來取得兩欄中的最大值
這裡學到的是 QUERY() 這個公式
利用 QUERY() 我可以選出兩欄中最大的那一欄
不過 QUERY() 第二參數是類似 SQL 的語法
因此必須先做一次 TRANSPOSE() 把列與行對換
才能用 MAX() 語法取得最大值 (非常自找麻煩)

QUERY() 應用

最後就是再把結果 TRANSPOSE() 一次然後選出數字的那欄
就能餵到 RANK() 的第二參數中
非常囉嗦的方法,但是這樣就不必有輔助欄了

沒有留言:

張貼留言