- LegiNote 專案開發故事2 - 技術堆疊與 Worker
- LegiNote 專案開發故事的第二篇,內容涵蓋使用 Go 語言開發 Worker 的相關細節。介紹資料收集與更新邏輯的實作,以及專案的架構方式。
AI 翻译的文章。
durumis AI 总结的文章
- 在開發 LegiNote 專案的過程中,我們使用國會 OpenAPI 取得法案資訊。
- 我們使用 Go 語言透過 HTTP Request 請求資料,並將接收到的 JSON 資料解析成結構體。
- 本文說明了從 API 認證金鑰取得、資料請求到解析的整個過程,並探討未來的改進方向。
您好,我是 StatPan。
正在撰寫 LegiNote 這個副程式專案的開發日誌。
請參考以下連結查看前一篇。
工作者 1 號 worker-bill
bill 這個名字聽起來很像外國朋友的名字,感覺很親切,這個名字的靈感來源於以下詞彙的含義。
為了找到合適的變數名和儲存庫名稱,之前我搜尋過一些與國會領域相關的英文單詞,現在我將之前找到的詞彙應用於此。
bill 字詞的含義
工作者(Worker)要收集數據的目標 OpenAPI 規格如下所示。
輸入參數
法案審查及處理 API 輸入參數
輸出參數
法案審查及處理 API 輸入參數
提供的數據量很大,看起來可以提供相當詳細的資訊。
Http 請求準備事項
首先,讓我們看看要進行上述輸入參數的 Http 請求需要哪些東西。
URL、Http 請求方法(這裡沒有說明,但方法是 Get,不支援 Post 方法ㅠ)、KEY、Type、pIndex、pSize的值。
KEY 值與其他 OpenAPI 類似,需要您單獨獲取授權金鑰。
由於這裡是開發日誌,如果有參考連結,我通常會附上,但由於這個 API 仍然比較小眾,因此在 Google 上找不到關於如何獲取授權金鑰的文章…… 因此,我將在此處主要以圖示的方式簡單說明…
首頁
點擊首頁上的「我的頁面」按鈕。
我的頁面
認證金鑰發放畫面
在上述畫面中,關於使用目的或內容,我簡單地寫了「公眾數據競賽用途」。在填寫內容的部分,不用太擔心,只要不是 1~2 行不當(?)的理由,我認為應該會立即獲批。
這樣獲取到的金鑰就是上述 HTTP 說明中所需的 KEY。
我們將嘗試向上述 URL 發送一次請求(希望在下次更新時能包含方法)
go```go package main import ( "encoding/json" "fmt" "io" "log" "net/http" "net/url" ) func procErr(e error, msg string) { if e != nil { log.Fatal(e, msg) } } func main() { rawUrl := "https://open.assembly.go.kr/portal/openapi/TVBPMBILL11" parsedUrl, err := url.Parse(rawUrl) procErr(err, "err after parsedUrl") params := url.Values{} KEY := "your_key" //change this procErr(err, "err after req, 27") req.Header.Add("Content-Type", "application/json") req.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36") params.Add("KEY", KEY) params.Add("Type", "json") // JSON 좋.아 params.Add("pIndex", "1") // 이건 왜 integer로 표시했는지 모르겠지만 string params.Add("pSize", "1") client := &http.Client{} reqURL := fmt.Sprintf("%s?%s", rawUrl, params.Encode()) req, err := http.NewRequest(http.MethodGet, reqURL, nil) res, err := client.Do(req) procErr(err, "err, after client do") defer res.Body.Close() var jsonMap any response, err := io.ReadAll(res.Body) procErr(err, "err after read response") err = json.Unmarshal(response, &jsonMap) procErr(err, "err after json unmarshal") fmt.Println(jsonMap)
```
通過上述代碼,我驗證了其功能。
給大家一個小提示,您必須添加 Header。如果您想順利使用該 API,請務必添加(半威脅)
之後,我們將在 Get URL 中填寫必要的參數。
pIndex 和 pSize 的值雖然說明需要使用整數,但使用字串類型也能正常工作。(無法理解)
Type 也可以使用 xml 格式,但我選擇了 Json 格式。
結果值
map[TVBPMBILL11:[map[head:[map[list_total_count:103305] map[RESULT:map[CODE:INFO-000 MESSAGE:正常處理되었습니다.]]]] map[row:[map[AGE:22 BILL_ID:PRC_T2U4C0A8B2Z0A1Y3Y5G2H0F0G5E4F4 BILL_NAME:政治資金法部分修正法律案 BILL_NO:2203179 CMT_PRESENT_DT: CMT_PROC_DT: CMT_PROC_RESULT_CD: COMMITTEE_DT: COMMITTEE_PROC_DT: CURR_COMMITTEE: CURR_COMMITTEE_ID: LAW_PRESENT_DT: LAW_PROC_DT: LAW_PROC_RESULT_CD: LAW_SUBMIT_DT: LINK_URL:https://likms.assembly.go.kr/bill/billDetail.do?billId=PRC_T2U4C0A8B2Z0A1Y3Y5G2H0F0G5E4F4 PROC_DT: PROC_RESULT_CD: PROPOSER:高東振議員等 10 人 PROPOSER_KIND:議員 PROPOSE_DT:2024-08-23 RST_MONA_CD:HS39431V RST_PROPOSER:高東振] map[AGE:22 BILL_ID:PRC_O2M4M0L8L2T0R1S3Q5R1P4Q0Y2W2X6 BILL_NAME:政黨法部分修正法律案 BILL_NO:2203178 CMT_PRESENT_DT: CMT_PROC_DT: CMT_PROC_RESULT_CD: COMMITTEE_DT: COMMITTEE_PROC_DT: CURR_COMMITTEE: CURR_COMMITTEE_ID: LAW_PRESENT_DT: LAW_PROC_DT: LAW_PROC_RESULT_CD: LAW_SUBMIT_DT: LINK_URL:https://likms.assembly.go.kr/bill/billDetail.do?...
可以獲得上述結果。
我另外定義了所有結構體來直接控制該物件並獲取值,這也經過了無數次的調試。
由於字數限制,將結構體解碼(Unmarshal)到結構體的過程可能需要在下一篇文章中繼續。
一個請求就佔用了開發日誌的一篇文章。當然,由於這個 OpenAPI 的使用特性,在 API 使用和結構體結構方面確實花費了大量時間。我需要找到一種方法,讓其他人避免經歷同樣的痛苦。
如果上述請求中出現任何預期外的行為或您對我的奇怪代碼有任何不滿,請務必提供香煙。