한장재 블루리본: 공개 지출 기록으로 오늘 점심 후보를 찾기까지
공공기관 업무추진비에 적힌 식당 이름을 오늘 점심 후보로 바꿨습니다. 자료 정제와 동명 매장 처리부터 위치·영업시간 필터, 저장과 식당 뽑기까지 한장재 블루리본을 만든 과정을 기록합니다.
목차
안녕하세요 mouseco 입니다. :)
이번에 만든 것은 오늘 점심을 어디서 먹을지 고르는 작은 식당 가이드, 한장재 블루리본입니다. 한국장학재단 본사·별관 주변에서 점심이나 저녁, 커피 마실 곳을 찾는 장면을 출발점으로 삼았습니다.
식당을 찾는 서비스는 이미 많습니다. 여기에 제가 더해 보고 싶었던 것은 공공기관의 공개 업무추진비 기록이었습니다. 문서 속에 흩어진 식당 이름을 모아 위치와 함께 보여주면, 주변에서 갈 만한 곳을 고르는 또 하나의 단서가 되겠다고 보았습니다.
그런데 엑셀에 있는 식당 이름을 지도에 올리는 데에는 생각보다 여러 판단이 필요했습니다. 어떤 기록을 남길지, 같은 이름의 어느 지점에 연결할지, 영업시간을 모르는 식당을 목록에서 빼도 되는지. 이번 글은 그 판단들이 화면에 어떻게 반영됐는지에 관한 기록입니다.
점심시간에 쓸 수 있는 한 화면부터
처음 정한 사용 장면은 구체적이었습니다. 기준 위치를 고르고, 주변 식당을 좁힌 뒤, 한 곳을 골라 지도까지 넘어가는 것입니다. 목록에서 이름을 확인한 사람이 다시 검색창을 열고 주소를 찾는 일을 줄이는 데 초점을 맞췄습니다.
현재 화면에서는 본사·별관이나 현재 위치를 기준으로 후보를 살펴볼 수 있습니다. 식사 시간대와 거리 등을 바꾸고, 목록과 지도를 오가며, 식당 상세에서 주소와 관련 정보를 확인합니다. 마음에 드는 곳은 저장하고, 고르기 어려울 때는 식당 뽑기로 후보를 정할 수 있게 했습니다.
공개 기록을 넓게 살펴보는 흐름과 한국장학재단 관련 후보를 보는 흐름도 마련했습니다. 이후 추천·후기 기능이 더해지면서 공시에서 찾은 장소와 사람이 추천한 장소를 함께 살펴보는 가이드로 확장됐습니다.
엑셀을 합치기 전에, 한 줄이 무엇인지 정하기
출발 자료는 기관별로 정리한 업무추진비 엑셀이었습니다. 년월, 기관명, 집행내용, 매장명, 집행금액을 공통 기준으로 맞추고 SQLite에 모으는 구조를 만들었습니다. 원본에 인원 정보가 있으면 별도로 보존합니다.
여기서 상호가 적혀 있다는 이유만으로 모두 식당 목록에 넣을 수는 없었습니다. 마트나 온라인 결제 표기가 섞일 수 있고, 체인 이름만 있어 지점을 알 수 없는 기록도 있습니다. 여러 상호가 한 줄에 묶여 있으면 그 지출을 어느 한 식당의 기록으로 돌릴 근거가 부족합니다.
그래서 입력을 다음처럼 나눴습니다.
| 원문에서 확인한 상태 | 처리 방향 |
|---|---|
| 식당·카페 후보로 볼 수 있는 상호 | 후보로 유지 |
| 비음식 소매점이나 온라인 결제 표기 | 제외 사유를 남김 |
| 지점이 없는 체인명, 복수 상호, 매장 불명 수취인 | 추가 확인 대상으로 보류 |
이 과정에서 빠진 행을 그냥 버리지 않는 것이 중요했습니다. 유지한 행과 제외·보류한 행을 합쳤을 때 입력과 맞는지 확인하고, 원본 파일과 행을 다시 찾을 수 있도록 추적 정보를 남겼습니다. 같은 입력을 다시 처리할 때에는 덧붙이기보다 DB를 재생성해 중복 적재를 피하도록 했습니다.
그 덕분에 화면의 숫자가 이상할 때도 “수집이 잘됐겠지”에서 멈추지 않고, 어느 원문에서 나온 기록인지 거슬러 확인할 길을 갖게 됐습니다.
같은 이름이라고 같은 식당은 아니다
다음은 장소 연결이었습니다. 카카오 로컬 검색으로 주소·좌표·업종·지도 링크를 찾되, 검색 결과가 나왔다는 사실과 실제 결제 지점이 확인됐다는 사실을 구분해야 했습니다.
예를 들어 지점이 없는 체인명에 가장 가까운 검색 결과를 붙이면 지도는 그럴듯해집니다. 하지만 그 기관이 그 지점에서 지출했다는 근거는 생기지 않습니다. 그래서 동명 매장이나 지점이 불분명한 경우에는 후보와 판정 근거를 남기고, 임의로 확정하지 않는 방향으로 처리했습니다.
주소를 확인해 연결한 결과도 다시 수집할 때 사라지지 않도록 별도로 보존했습니다. 특히 특정 기관의 기록을 확인한 경우에는 다른 기관의 같은 이름까지 한꺼번에 옮기지 않도록 범위를 제한했습니다. 식당 하나를 정리하는 일이 전체 집계를 잘못 바꾸지 않게 하기 위한 선택입니다.
공시 기록 건수는 실제 방문 횟수나 맛에 대한 점수가 아닙니다.
이 기준은 서비스 설명에도 필요합니다. 현재 화면에 함께 나오는 공시 기록, 이용자 추천·후기, 카카오 평점은 각각 출처와 의미가 다릅니다. 한 숫자로 합쳐 “검증된 맛집”이라고 부르기보다, 고르는 사람이 무엇을 근거로 보고 있는지 알 수 있게 해야 합니다.
화면을 고칠 때 데이터까지 건드리지 않도록
자료 수집과 정제에는 Python과 SQLite를 쓰고, 화면은 HTML·CSS·JavaScript로 구성했습니다. 작업이 이어지면서 화면 소스를 frontend/로 분리했습니다.
빌드 단계는 화면 자산을 미리보기 폴더로 옮기고 기존 진입점을 연결합니다. 데이터는 기준 DB에서 별도 JSON으로 생성합니다. 버튼 간격이나 카드 배치를 바꾸는 작업 때문에 원본 데이터와 집계가 함께 바뀌지 않도록 수정 경계를 나눈 것입니다.
식당 상세처럼 외부 정보가 필요한 부분은 별도로 조회합니다. 상세 조회가 실패해도 저장된 기본정보와 지도 링크를 통해 다음 행동을 이어갈 수 있도록 구성했습니다. 목록을 보는 일 전체가 외부 응답 하나에 달리지 않게 하는 쪽입니다.
영업시간을 모른다고 목록에서 사라지면
점심·저녁 구분은 처음부터 간단한 문제가 아니었습니다. 지출 목적에 “점심”이 적혔다고 오늘도 점심 장사를 한다고 볼 수 없으므로, 등록된 영업시간으로 시간대 후보를 나누는 방식을 택했습니다. 브레이크타임과 라스트오더도 판단에 반영합니다.
그런데 시간표를 확보하지 못한 식당까지 모두 빼면 또 다른 문제가 생깁니다. 영업시간을 모른다는 이유가 식당을 보여주지 않을 이유로 바뀌는 것입니다. 초기 기획에서는 미확인 식당을 전체 목록에 남기도록 했지만, 이후 구현에서는 점심·저녁 목록에도 포함하고 미확인 상태를 안내하도록 수정했습니다.
등록된 시간표가 있어도 임시 휴무나 실제 주문 가능 여부까지 보장하지는 않습니다. 그래서 이 필터는 식사 후보를 좁히는 도구로 설명하고, 방문 전에는 상세정보나 외부 지도로 확인할 수 있게 했습니다.
위치 선택도 같은 맥락에서 다듬었습니다. 본사와 별관의 기본 검색 반경을 다르게 두고, GPS를 쓰기 어려울 때는 위치 검색으로 이어갈 수 있게 했습니다. 기능 하나를 더 넣기보다, 지금 조건에서 후보가 나오지 않는 이유와 다음 행동을 보여주는 일이 필요했습니다.
지금 공개한 것과 앞으로 확인할 것
현재 lunch.mouseco.kr에서 식당 가이드를 공개하고 있습니다. 위치와 조건에 따른 후보 탐색, 목록·지도 전환, 상세정보, 저장, 식당 뽑기, 추천·후기 흐름을 갖췄습니다. 공개 업무추진비 자료를 식사 장소 선택에 연결하는 서비스가 첫 결과물입니다.
이 글에서는 이용자 수나 점심 선택 시간의 단축 같은 성과를 붙이지 않았습니다. 그런 효과는 실제 사용을 통해 확인해야 합니다. 다음으로 살펴볼 것은 후보를 찾은 사람이 상세정보와 지도까지 자연스럽게 이동하는지, 미확인 정보가 선택을 얼마나 방해하는지입니다.
데이터도 계속 확인할 부분이 남아 있습니다. 수집한 자료에는 기관·기간별 범위가 있고, 장소 연결과 영업시간에도 불확실성이 있습니다. 공개 기록이 있다는 것, 그 기록이 어느 매장과 연결되는지, 지금 방문할 수 있는지는 각각 따로 확인할 문제로 남겨두고 개선해 나가려 합니다.
한장재 블루리본은 한국장학재단 및 블루리본 서베이와 관계없는 개인 운영 비공식 서비스입니다.