지난 데이터 파이프라인 아키텍처 기획에 이어, 이번 포스팅에서는 외부의 비정형 공공 데이터를 우리 시스템으로 끌어오는 3계층 중 첫 번째, 수집 계층(Ingestion Layer)의 파이썬(Python) 코드를 직접 구현해 봅니다.
실제 현업에서 조달청 나라장터(G2B)나 한국토지주택공사(LH)의 입찰 데이터를 수집해 보면, 교과서적인 API 호출만으로는 해결되지 않는 수많은 변수와 마주하게 됩니다. 단순한 데이터 스크래핑을 넘어, 서버 차단을 방지하고 예외 상황을 철저히 통제하는 실무 엔지니어링 노하우를 공유합니다.
1. REST API 기반 실시간 데이터 호출과 JSON 파싱
가장 빠르고 안정적인 데이터 수집 방식은 공공데이터포털이 제공하는 Open API를 활용하는 것입니다.
- requests 모듈 활용: 파이썬의
requests.get()함수를 사용하여 엔드포인트 URL에 인증 키(Service Key)와 검색 파라미터(날짜, 기관 코드 등)를 담아 호출합니다. - JSON 데이터 구조화: 응답받은 데이터는 대부분 JSON 포맷으로 이루어져 있습니다. 파이썬 내장
json라이브러리를 통해 이 문자열을 딕셔너리(Dictionary)로 변환하면,['response']['body']['items']와 같이 직관적인 키(Key) 값으로 필수 입찰 정보에 접근할 수 있습니다. - [실무 트러블슈팅]: 공공 API 서버는 트래픽이 몰릴 때 HTTP 500(내부 서버 에러)을 반환하는 경우가 잦습니다. 한 번의 에러로 스크립트가 완전히 종료되지 않도록
while루프와 재시도(Retry) 로직을 반드시 추가해야 결측치를 막을 수 있습니다.
2. 하이브리드 수집: BeautifulSoup을 활용한 상세 텍스트 추출
API에서 제공하지 않는 세부 입찰 참가 자격이나 복잡한 첨부파일 내역은 불가피하게 웹 크롤링 기법을 병행하여 긁어와야 합니다.
- DOM 트리 탐색:
BeautifulSoup라이브러리를 사용하여 복잡하게 얽힌 G2B 웹페이지의 HTML 구조를 파싱합니다. - 정밀한 CSS Selector 지정: 브라우저의 개발자 도구(F12)를 활용해 원하는 텍스트가 담긴
<div>나<td>태그의 클래스명을 추적하고 정교하게 발췌합니다. - [실무 트러블슈팅]: G2B 상세 페이지는 보안을 이유로 여러 개의 Iframe이 중첩되어 있는 경우가 많습니다. 겉보기에 노출된 URL이 아닌, 실제 텍스트 데이터가 렌더링 되는 내부 프레임의 ‘진짜 원본 URL’을 네트워크 탭에서 찾아내어 별도로 요청을 보내는 것이 핵심 기술입니다.
3. 방어적 코딩: IP 차단 회피 및 무중단 예외 처리
엔터프라이즈 데이터 파이프라인의 생명은 ‘무중단’입니다. 수집 봇이 공공기관 방화벽에 차단당하거나 런타임 에러로 멈추는 것을 원천 봉쇄해야 합니다.
- 동적 Time Sleep 적용: 반복문 사이의 고정된 대기 시간(예: 2초)은 방화벽의 매크로 탐지 패턴에 적발되기 쉽습니다.
time.sleep(random.uniform(1.5, 3.5))와 같이 난수를 발생시켜 사람의 클릭 패턴처럼 트래픽을 유연하게 분산시켜야 합니다. - 결측치 통제(Try-Except): 수집 도중 특정 공고가 갑자기 취소되어 태그가 아예 사라지는 경우가 빈번합니다. 데이터를 추출하는 핵심 로직을
try-except블록으로 감싸고, 에러 발생 시 강제 종료 대신None값을 부여한 뒤 시스템 로그(Log) 파일에 해당 공고 번호만 기록하도록 설계해야 합니다.
결론: 거친 데이터를 길들이는 든든한 첫 단추
이러한 방어적 코딩과 치열한 트러블슈팅을 거쳐야만 비로소 365일 24시간 알아서 돌아가는 신뢰할 수 있는 수집 봇이 완성됩니다. 하지만 이렇게 악착같이 긁어온 데이터도 여전히 발주처 이름과 단위가 제각각인 ‘날것(Raw)’ 상태입니다.
다음 포스팅에서는 이 거친 데이터를 우리가 지난 시즌에 확립했던 ‘전사 MDM 기준 정보 모델’에 맞춰 깔끔하게 통일하는 ‘파이썬 pandas 기반 수집 데이터 표준화 및 정규화(Normalization) 실무’ 과정을 깊이 있게 해부해 보겠습니다.