XBRL 재무제표 원문과 주석 다운로드 파이프라인
Quick Summary

OpenDART에서 재무제표를 제대로 수집하려면 JSON API만 보면 안 된다. corp_code, 접수번호, 공시서류원본파일, XBRL 원문, 주석 일괄다운로드를 어떤 순서로 연결해야 하는지 실전 파이프라인 기준으로 정리한다.

XBRL 재무제표 원문과 주석 다운로드 파이프라인

OpenDART를 처음 쓰면 대개 단일회사 주요계정이나 단일회사 전체 재무제표 같은 JSON API부터 본다. 여기까지만 보면 충분해 보인다. 숫자가 이미 구조화돼 있고, 호출도 쉽기 때문이다.

하지만 수집 파이프라인을 실제로 짜기 시작하면 곧 막힌다.

  • 종목코드로 바로 안 된다
  • 어떤 공시를 기준으로 잡아야 할지 헷갈린다
  • JSON만으로는 주석이나 원문 맥락이 부족하다
  • 정정공시나 첨부 원문을 어떻게 따라가야 하는지 애매하다

즉 OpenDART는 endpoint 몇 개를 외운다고 끝나는 시스템이 아니다. corp_code -> 접수번호(rcept_no) -> 공시서류 원문 -> XBRL 원문 -> 주석 파일의 흐름으로 이해해야 비로소 안정적인 파이프라인이 된다.

이 글은 무슨 API가 있나를 나열하지 않는다. 대신 정기보고서 재무 수집기를 실제로 설계할 때 어떤 소스를 어떤 순서로 붙여야 하는가를 중심으로 정리한다.

OpenDART 재무 수집의 전체 흐름을 보여주는 pipeline overview


왜 JSON API만으로는 부족한가

JSON API는 빠르고 편하다. 스크리닝, 비교, 대략적인 시계열 확인에는 아주 좋다. 문제는 이 레이어가 정답 전체는 아니라는 점이다.

JSON API만으로 부족해지는 순간은 보통 아래 네 가지다.

막히는 순간왜 JSON만으로 부족한가필요한 다음 레이어
어떤 공시 기준 숫자인지 확인하고 싶다접수번호와 원문 맥락이 빠질 수 있다공시검색, 공시서류원본파일
주석 세부 내역이 필요하다재고, 차입금, 리스, 충당부채는 원문/주석이 중요하다주석 다운로드
XBRL 원문 태그를 직접 확인하고 싶다정규화 전 원본 태그가 필요하다재무제표 원본파일(XBRL)
정정공시와 원본 차이를 추적하고 싶다숫자만으로는 수정 맥락이 안 보인다공시서류원본파일, 검색 결과

즉 JSON API는 조회 레이어로 좋지만, 수집기 관점에서는 원문과 파일 레이어를 붙여야 파이프라인이 닫힌다.


첫 단추는 종목코드가 아니라 corp_code다

초보자가 제일 많이 틀리는 부분이 여기다. OpenDART의 기본 식별자는 종목코드가 아니라 corp_code다.

그래서 재무 수집기의 첫 단계는 “삼성전자 = 005930”이 아니라, 005930을 그 회사의 corp_code로 연결하는 단계다.

실전 순서는 단순하다.

  1. corp_code 파일을 받아서 회사 식별 테이블을 만든다.
  2. 종목코드와 corp_code를 매핑한다.
  3. 이후 OpenDART 호출은 corp_code를 기준으로 간다.

이 단계를 건너뛰면 나중에 검색, 공시 원문, 파일 다운로드를 붙일 때 전부 다시 돌아와야 한다.


접수번호를 잡지 못하면 파이프라인이 흔들린다

corp_code가 회사 식별자라면, rcept_no는 문서 식별자다.

많은 수집기가 여기서 약하다. 재무 숫자는 받았는데, 그 숫자가 어떤 접수번호의 어떤 보고서에 묶여 있는지 끝까지 들고 가지 않는다. 그러면 나중에 아래 문제가 생긴다.

  • 정정공시가 나와도 어느 문서를 대체해야 하는지 모른다
  • 원문 HTML이나 첨부 파일을 열 수 없다
  • XBRL 원문과 JSON 숫자를 연결하기 어렵다
  • 같은 연도 안에서도 어떤 보고서를 기준으로 쓸지 애매하다

그래서 좋은 수집기는 회사 식별 = corp_code, 문서 식별 = rcept_no를 끝까지 함께 든다.


소스는 하나가 아니라 층이다

OpenDART 재무 수집을 잘하는 사람은 “무슨 API를 써야 하지”라고 묻지 않는다. 대신 지금 필요한 정보가 어느 층에 있는가를 먼저 묻는다.

JSON, raw filing, XBRL, notes를 역할별로 나눈 source selection map

아래처럼 보면 빠르다.

레이어잘하는 일부족한 점
공시검색 / 보고서 메타어떤 문서를 잡아야 하는지 결정숫자는 약하다
재무 JSON API빠른 조회, 비교, 스크리닝원문 맥락과 주석은 부족
공시서류원본파일문서 원형과 첨부 추적후처리 비용이 높다
XBRL 원문파일태그 레벨 원본 검증사람이 읽기엔 불편하다
주석 다운로드세부 계정 주석 회수파일 단위 처리와 정규화가 필요

좋은 파이프라인은 한 소스를 만능처럼 쓰지 않는다. 탐색은 검색, 숫자는 JSON, 원형 검증은 원문/XBRL, 깊이는 주석으로 역할을 나눈다.


언제 XBRL 원문이 필요하고 언제 JSON이면 충분한가

이 질문을 분리하지 못하면 수집기가 불필요하게 무거워진다.

JSON API, raw filing, XBRL 원문, notes download의 역할 차이를 비교한 matrix

실전 기준은 이렇다.

JSON이면 충분한 경우

  • 기업 간 비교용 숫자를 빠르게 모을 때
  • 시계열 스크리닝을 할 때
  • 당장 주석 세부까지는 필요 없을 때

XBRL 원문이 필요한 경우

  • 계정 태그를 직접 검증해야 할 때
  • 정규화 전 원본 레이어를 남겨야 할 때
  • 회사별 태그 차이나 계정 매핑 문제를 확인해야 할 때

공시서류원본파일이 필요한 경우

  • 문서 전체 맥락과 첨부 구조를 봐야 할 때
  • 정정공시 전후 원문을 비교해야 할 때
  • 원문에만 있는 조건이나 표를 확인해야 할 때

주석 다운로드가 필요한 경우

  • 재고, 차입금, 리스, 충당부채 같은 세부 주석이 필요할 때
  • 표준 JSON API로는 회수되지 않는 세부 구조가 필요할 때
  • LLM이나 후처리 파서에 넣을 원천 텍스트/표가 필요할 때

핵심은 단순하다. JSON은 빠른 답, XBRL과 원문은 검증, 주석 파일은 깊이다.


실전 파이프라인은 어떻게 짜야 하나

안정적인 기본형은 아래 순서가 좋다.

  1. corp_code 사전을 만든다.
  2. 회사별로 공시검색에서 기준 보고서를 잡는다.
  3. 기준 보고서의 rcept_no를 저장한다.
  4. JSON 재무 API를 우선 호출해 구조화 숫자를 모은다.
  5. 같은 rcept_no 기준으로 공시서류원본파일 또는 XBRL 원문을 붙인다.
  6. 필요한 회사에 한해 주석 다운로드를 태운다.
  7. 정정공시가 있으면 같은 흐름으로 다시 매칭한다.

이 구조의 장점은 분명하다.

  • 속도는 JSON이 책임진다
  • 추적성은 rcept_no가 책임진다
  • 검증은 XBRL과 원문이 책임진다
  • 세부 깊이는 주석 다운로드가 책임진다

즉 처음부터 모든 회사를 무겁게 처리하지 말고, 가벼운 레이어에서 무거운 레이어로 단계적으로 내려가는 구조가 좋다.

주석 다운로드를 파이프라인 뒤쪽에서 붙이는 note extraction flow


정정공시를 파이프라인에 어떻게 반영해야 하나

정정공시는 수집기를 가장 쉽게 흔드는 요소 중 하나다. 같은 회사, 같은 연도, 같은 보고서처럼 보여도 실제로는 문서 버전이 달라질 수 있기 때문이다.

그래서 파이프라인에서는 아래를 분리해서 들고 가는 편이 안전하다.

  • 회사 식별자: corp_code
  • 문서 식별자: rcept_no
  • 보고서 유형과 기간
  • 원본/정정 여부

이 구조가 없으면 숫자만 갱신되고 왜 바뀌었는지 맥락은 사라진다. 반대로 문서 버전이 남아 있으면, 정정 전후 차이를 비교하거나 특정 숫자가 어느 시점에 바뀌었는지 추적하기 쉬워진다.


다운로드 이후 저장 구조는 어떻게 잡는 것이 좋은가

수집 파이프라인은 다운로드로 끝나지 않는다. 저장 구조가 약하면 나중에 다시 연결할 때 거의 처음부터 다시 해야 한다.

실전에서는 최소한 아래 단위가 구분돼 있으면 좋다.

  • 회사 기준 디렉터리 또는 테이블
  • 문서 기준 메타데이터
  • JSON 숫자 레이어
  • 원문/XBRL 파일 레이어
  • 주석 추출 또는 후처리 레이어

이렇게 분리해두면 빠른 스크리닝은 JSON만 읽고, 원문 검증은 XBRL이나 공시 원문만 읽고, 깊은 분석은 주석 레이어만 읽는 식으로 비용을 분리할 수 있다. 결국 좋은 저장 구조는 성능 최적화이면서, 동시에 추적 가능성 설계이기도 하다.


이 파이프라인을 읽고 나서 다음으로 무엇을 붙이면 좋은가

이 글은 재무 수집 허브다. 여기서 끝내지 말고 목적에 따라 다음 파이프라인으로 이어가면 좋다.

다음 목적이어서 볼 글
이벤트 감지까지 붙이고 싶다OpenDART로 주요사항보고서 읽는 법
OpenDART의 장단점을 먼저 정리하고 싶다OpenDART, 솔직한 리뷰
분석 코드까지 바로 이어가고 싶다파이썬으로 재무제표 분석하기

좋은 파이프라인 글은 endpoint 목록이 아니라, 어떤 레이어를 어떤 순서로 붙여야 하는가를 남겨야 한다. 이 글의 목적도 정확히 거기에 있다.


실패하는 수집기의 공통 패턴

중복 수집이나 누락은 대부분 복잡한 알고리즘보다 기본 설계 실수에서 나온다.

1. corp_code를 별도 단계로 관리하지 않는다

종목코드만 들고 가면 결국 중간에 다시 corp_code로 돌아와야 한다.

2. rcept_no를 버린다

문서 식별자를 버리면 원문 연결, 정정 추적, 첨부 다운로드가 다 약해진다.

3. JSON을 만능 레이어로 쓴다

빠른 조회에는 좋지만, 원문 검증과 주석 회수는 다른 레이어가 필요하다.

4. 모든 회사에 XBRL과 주석을 한 번에 태운다

그렇게 하면 수집 속도와 저장비용이 급격히 나빠진다. 먼저 JSON으로 좁히고 필요한 곳만 내려가야 한다.

5. 정정공시를 원문 기준으로 다시 묶지 않는다

숫자만 갱신하면 왜 바뀌었는지 설명이 사라진다.

실패하는 파이프라인의 병목을 정리한 failure recovery checklist


실전 체크리스트

  • corp_code 사전이 먼저 정리돼 있는가
  • 검색 결과에서 기준 보고서와 rcept_no를 저장하는가
  • JSON API 결과가 어떤 문서에 매핑되는지 끝까지 추적하는가
  • XBRL 원문은 검증 레이어로, 주석 파일은 심화 레이어로 분리했는가
  • 모든 회사를 무겁게 처리하지 않고 단계적으로 내려가는가
  • 정정공시가 나오면 같은 문서 흐름으로 다시 연결되는가

FAQ

종목코드만으로 바로 파이프라인을 짜면 안 되나

처음엔 가능해 보여도 결국 corp_code 단계가 필요해진다. 초반에 정리하는 편이 훨씬 낫다.

JSON API만 있으면 XBRL 원문은 안 봐도 되나

비교와 스크리닝만 할 때는 그럴 수 있다. 하지만 원본 태그 검증이나 주석 깊이가 필요하면 부족하다.

접수번호는 왜 그렇게 중요한가

문서를 식별하는 축이기 때문이다. 원문, 첨부, 정정공시 추적이 전부 여기에 걸린다.

주석 다운로드는 언제 붙이는 것이 가장 좋은가

기본 수집을 끝낸 뒤 필요한 회사와 보고서에만 선택적으로 태우는 편이 좋다.

가장 흔한 실수는 무엇인가

JSON을 곧 원본이라고 착각하는 것이다. OpenDART는 레이어가 여러 개고, 역할도 다르다.


참고한 공식 자료


같이 읽으면 좋은 글


정리

OpenDART 재무 수집의 핵심은 endpoint를 많이 아는 것이 아니다. 회사 식별은 corp_code, 문서 식별은 rcept_no, 빠른 조회는 JSON, 원형 검증은 XBRL/원문, 깊이는 주석 다운로드라는 층을 정확히 나누는 것이다.

이 구조만 잡으면 수집기는 훨씬 안정적이고, 나중에 정정공시나 세부 주석까지 붙일 때도 무너지지 않는다. 좋은 파이프라인은 많이 받는 파이프라인이 아니라, 어떤 레이어를 언제 내려가야 하는지 아는 파이프라인이다.

같은 시리즈에서 이어 읽기
DartLab

같은 카테고리에서 더 읽기

DartLab은 데이터 자동화 카테고리 안에서 글이 서로 이어지도록 설계합니다. 다음 글로 넘어가며 구조와 맥락을 같이 쌓는 방식입니다.

DartLab Product

이 글의 판단을 실제 데이터 흐름으로 옮기기

DartLab은 전자공시를 읽는 법을 코드와 데이터로 연결하기 위해 만든 제품입니다. 사업보고서 텍스트, 재무 시계열, 정기보고서 데이터를 한 흐름에서 다루도록 설계했습니다.