- История разработки проекта LegiNote 2 - стек технологий и воркеры
- Вторая часть истории разработки проекта LegiNote, посвященная разработке воркеров на языке Go. В ней описывается реализация логики сбора и обновления данных, а также структура проекта.
Текст, переведенный ИИ.
Резюме публикации от ИИ durumis
- В ходе разработки проекта LegiNote была реализована задача получения информации о законопроектах с использованием открытого API Национального собрания.
- С помощью языка Go были отправлены HTTP-запросы для получения данных, а полученные данные в формате JSON были проанализированы с помощью структур.
- В статье описывается процесс от получения ключа API до запроса данных и их анализа, а также рассматриваются направления дальнейшего развития проекта.
Здравствуйте, это StatPan.
Я пишу о разработке сайд-проекта LegiNote.
Пожалуйста, обратитесь к следующей ссылке для предыдущей части.
Рабочий №1 worker-bill
Имя «bill» звучит как-то знакомо, как имя иностранного друга. Вдохновение для него я получил от следующего значения слова.
Ранее я искал различные английские слова, связанные с доменом Национального собрания, чтобы найти подходящие имена переменных и репозиториев. И я использовал найденное тогда.
Значение слова bill
Спецификация OpenAPI, на которую нацелен Worker для сбора данных, выглядит следующим образом:
Входные параметры
Входные параметры API для проверки и обработки законопроектов
Выходные параметры
Входные параметры API для проверки и обработки законопроектов
Похоже, что предоставляется много данных, и можно обслуживать довольно подробную информацию.
Необходимые компоненты HTTP-запроса
Прежде всего, давайте посмотрим, что необходимо для отправки HTTP-запроса с указанными выше входными параметрами.
URL, метод HTTP-запроса(хотя здесь это не указано, Get, Post не поддерживается ㅠ), KEY, Type, pIndex, pSize значения.
Что касается значения KEY, то, как и в случае с другими OpenAPI, вам необходимо получить отдельный ключ аутентификации.
Поскольку мы ведем рассказ о разработке, я хотел бы добавить ссылки на референсы… Но, видимо, из-за того, что API еще не очень популярен, в Google нет статей о том, как получить ключ аутентификации… Вместо этого давайте кратко рассмотрим это на примере картинок…
Главная страница
Нажмите кнопку «Моя страница» на главной странице.
Моя страница
Экран получения ключа API
В этом окне, в части «Цель использования» или «Содержание», я просто написал, что это для участия в конкурсе по открытым данным. Не стоит сильно беспокоиться о заполнении этой части. Думаю, если вы напишете 1-2 предложения, не содержащих ничего предосудительного (?), вам сразу же одобрят запрос.
Полученный таким образом ключ — это и есть ключ KEY, необходимый для описания HTTP выше.
Давайте отправим запрос на указанный выше 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 работал без проблем. (полушутка).
Затем заполняем обязательные параметры для URL Get.
Для значений pIndex и pSize указан тип integer, но вы можете использовать тип string, и все равно будет работать. (непонятно).
Тип 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?...
Можно получить результат, показанный выше.
Отдельно, для управления этим объектом, я определил все структуры и извлек значения. И это тоже потребовало много отладки.
Из-за ограничения по количеству символов, думаю, мне придется продолжить тему разбора этого объекта на структуры в следующей части.
Один запрос занял целую часть в рассказе о разработке. Конечно, учитывая особенности использования этого OpenAPI, на настройку API и структуры потребовалось много времени. Нужно найти способ, чтобы другие разработчики не проходили через те же трудности.
Если у вас возникли проблемы с выполнением какого-либо из запросов или вам не нравится мой странный код, пожалуйста, предоставьте мне сигареты.