AI를 활용한 공학적 연구 방법론
Session 5 · 동적 웹 페이지와 데이터 수집 전략
AI를 활용한 공학적 연구 방법론

동적 페이지와
데이터 수집 전략

Session 5 / 8

JS 렌더링 · AJAX · fetch · API vs 스크래핑 · 공공데이터포털

박수현 · aSSIST University · 2026

🎨 이미지 프롬프트(배경): "Two divergent paths — one through dense HTML forest with manual scraping, the other through clean API gateway with structured JSON streams, teal and purple tones, editorial illustration, 16:9, no text"

LLM · API · 웹스크래핑 기반 연구 데이터 파이프라인
AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

이번 시간을 마치면

개념적으로

  • CSR / SSR / SPA / SSG 의 차이를 구분
  • AJAX·fetch 의 동작 원리
  • API vs 스크래핑 의사결정 트리
  • ✅ Open API 의 인증 4가지 — API Key (단순키) / Bearer (토큰) / OAuth (위임 인증) / HMAC (해시 기반 서명)
  • 공공데이터포털 의 신청·키 발급 흐름

실습으로

  • ✅ 네이버 금융에서 숨은 JSON API 찾기 (도서 Ch.5 §1 패턴)
  • ✅ 공공데이터 기상청 API 호출 → DataFrame
  • OpenAI / Claude API 로 텍스트 분류 맛보기

📖 도서 매핑: Ch.5 §1~2 + Ch.8 §1~3

PART A

정적 vs 동적
개념 다시 정리

회차 1 의 그림이 이번 회차의 출발점

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

현대 웹의 4가지 렌더링 패턴 — SSR / CSR / SSG / SPA

📋 4가지 패턴

패턴 동작 난이도
SSR (Server-Side Rendering) 서버가 매 요청마다 데이터 + HTML 합쳐서 응답 쉬움
SSG (Static Site Generation) 빌드 타임에 모든 HTML 미리 생성 (정적 파일) 간단함
CSR (Client-Side Rendering) 빈 HTML + JS 만 응답 → 브라우저가 데이터 가져와 그림 어려움
SPA (Single Page Application) 한 HTML 로 시작, 페이지 전환마다 JS 가 화면만 갈아끼움 어려움 — CSR 의 일종

🎯 대표 사례

  • SSR: 네이버 뉴스, 정부 공지, 블로그
  • SSG: 개인 블로그(Jekyll, Hugo), 도서 사이트
  • CSR: 카카오 맵, 네이버 지도, 인스타그램
  • SPA: 디스코드 웹, 구글 메일, 노션

🔑 회차 3의 BS4가 100% 통하는 영역 = SSR + SSG.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서1Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

AJAX / fetch — 새로고침 없는 비동기 데이터 갱신

💻 fetch 가 하는 일

AJAX = 새로고침 없이 서버와 데이터를 주고받는 기법 (원래 XML, 지금은 JSON). DOM = 브라우저가 만든 HTML 트리.

// 페이지 로드 후, JS가 추가 데이터 요청
async function loadProducts() {
  const r = await fetch(
    "/api/products?page=1");
  const data = await r.json();
  // → DOM 에 동적으로 추가
  renderProducts(data.items);
}
loadProducts();

서버는 처음에 빈 컨테이너만 보냄.
JS 가 fetch → JSON 받기 → DOM 채우기.

🔄 클라이언트 ↔ 서버

  1. JSON API 직접 호출 ← 권장 (빠르고 안정적)
  2. 브라우저 흉내 (Selenium) — 회차 6 주제

🔑 JSON API 가 보이면 무조건 그쪽으로.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

도서 Ch.5 §1 — 다나와 검색 결과

📺 사용자가 보는 화면

상품 카드들이 격자로. 평범한 쇼핑 페이지.

🛠️ DevTools 의 진실

절차: F12 → Network 탭 → 상단 필터 Fetch/XHR 클릭
페이지가 로드되면서 여러 JSON 요청 발생.
상품 데이터는 JSON API 안에.

XHR = XMLHttpRequest, JS 가 만든 비동기 요청 (브라우저가 서버에 데이터 추가로 받는 통로)

📖 도서 참조: Ch.5 §1 — "JS가 늦게 채우는 데이터"

PART B

API 우선
전략

스크래핑은 마지막 카드

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

API vs 스크래핑 — 데이터 출처 선택 의사결정 트리

1

공식 Open API 가 있고 한도가 충분한가?

✅ "예" → 공식 API가장 안전·안정 (회차 5 — 공공데이터포털 등)

2

Network XHR/Fetch 에 숨은 JSON API 가 있나?

⚠️ "예" → JSON API 직접 호출회색지대 — 사이트 약관·robots.txt 점검 후 사용

3

위 둘 다 없다 — 마지막 카드

✅ HTML 스크래핑회차 3 (정적) · 회차 6 (Selenium)

🔑 우선순위

공식 API > 숨은 JSON > HTML 스크래핑 — 위에서부터 시도. 한 단계 내려갈수록 윤리·법적 위험 증가.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서1Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

API vs 스크래핑 — 7개 항목 비교

🍳 API = 주방에 주문서 넣기

서버가 요리(데이터) 를 만들어 응답.
스크래핑은 손님이 주방에 들어가서 직접 그릇 들고 나오는 격.

📊 7개 항목 비교

항목 공식 API 스크래핑
합법성 ✅ 명확 ⚠️ 회색
안정성 ✅ 계약된 스키마 ❌ DOM(HTML 트리) 변경 취약
속도 ✅ 1초 100건 🐢 1초 1~5건
인증 API 키 / OAuth 헤더 위장 (User-Agent 를 브라우저처럼 꾸미기)
변경 알림 deprecation 메일 (deprecation = 기능 폐기 사전 공지) ❌ 갑자기 깨짐
데이터 양 한도 있음 HTML 닿는 만큼
비용 일부 유료 무료 (서버 비용은 자기)

🎯 연구자 입장

첫 시도는 항상 API. 안 되면 그제서야 스크래핑.

PART C

공공데이터포털
data.go.kr

한국 연구자의 첫 API — 법적으로 가장 안전

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

공공데이터포털 (data.go.kr) — 한국 정부 공개 데이터 허브

🇰🇷 사이트 첫 화면

data.go.kr 첫 화면

data.go.kr — 회원가입 후 API 키 발급.

📚 제공 데이터 예

  • 기상청 — 단기예보·중기예보·관측
  • 국토교통부 — 실거래가, 교통량
  • 금융위 — 공시, 시장 통계
  • 관광공사 — 관광지·축제·이벤트
  • 보건복지부 — 의료기관·약국
  • 환경부 — 미세먼지·수질

7만+ 데이터셋 제공.

공공데이터포털

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

공공데이터포털 API 키 발급 — 5단계 절차

🪜 1·2·3 단계

  1. 회원가입 + 본인인증
  2. 원하는 데이터셋 검색
    (예: "기상청 단기예보 조회")
  3. 활용신청 클릭
    → 자동승인 / 1~2일 심사

🪜 4·5 단계

  1. 마이페이지 → 인증키 확인
    (서비스키 발급)
  2. 샘플 코드 다운로드
    (Python / Java / cURL)

⚠️ 두 가지 키

  • Encoding 키 = 특수문자(+/=)가 %2B%2F%3D 로 변환된 형태 — URL 에 직접 넣어 GET 호출할 때
  • Decoding 키 = 원본 그대로 — requests.get(url, params={...}) 처럼 라이브러리가 인코딩해줄 때

📌 보통 Decoding 키를 코드에 넣고, requests 가 params= 로 자동 인코딩.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API참고: examples/ch08/

기상청 단기예보 API — 30줄로 일주일치 호출

⚙️ ① 키·시각·좌표 준비

import requests, pandas as pd
from datetime import datetime, timedelta

API_KEY = "여기에-decoding-키-붙여넣기"

# base_time 은 02/05/08/11/14/17/20/23
# 8회 발표. 어제 0500 발표분이 안정적
yesterday = (
    datetime.now() - timedelta(days=1)
).strftime("%Y%m%d")
base_time = "0500"

url = (
    "http://apis.data.go.kr/1360000/"
    "VilageFcstInfoService_2.0/getVilageFcst"
)
params = {
    "serviceKey": API_KEY,
    "numOfRows": 1000, "pageNo": 1,
    "dataType": "JSON",
    "base_date": yesterday,
    "base_time": base_time,
    "nx": 60, "ny": 127,   # 서울 종로
}

📡 ② 호출 → JSON → DataFrame → CSV

r = requests.get(
    url, params=params, timeout=10)
data = r.json()

items = (
    data["response"]["body"]
        ["items"]["item"]
)
df = pd.DataFrame(items)
print(df.head())

df.to_csv(
    "weather.csv",
    index=False,
    encoding="utf-8-sig",
)

📌 격자 좌표 (nx, ny) 는 위경도가 아닌 기상청 5 km 격자값. 서울 종로 ≈ (60, 127). 다른 지역은 기상청 「격자좌표 파일」 참조.

🎯 30줄로 7일치 예보 1,000건. 회차 3의 50페이지 스크래핑보다 100배 빠름.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

공공데이터 API 호출을 만든 프롬프트

💬 Antigravity / ChatGPT 입력 air_quality.py

📋 prompt prompts/ch08_prompts.md 📄 example examples/ch08/air_quality.py

Python 스크립트 air_quality.py 를 만들어 줘.
목적: 공공데이터포털의 한국환경공단 "측정소별
실시간 측정정보 조회" API 로 서울 강남구 측정소의
최근 24건 미세먼지 데이터를 받아 DataFrame 으로
출력한다.

요구사항:
1. 라이브러리: requests, pandas, python-dotenv
2. .env 의 PUBLIC_DATA_KEY_DECODED (디코딩된
   일반 인증키) 를 load_dotenv() 로 읽기
3. 엔드포인트:
   http://apis.data.go.kr/B552584/
   ArpltnInforInqireSvc/getMsrstnAcctoRltmMesureDnsty
4. 쿼리 파라미터:
   - serviceKey: 환경변수값
   - numOfRows: 24
   - pageNo: 1
   - stationName: "강남구"
   - dataTerm: "DAILY"
   - ver: "1.3"
   - returnType: "json"   (XML 기본 → JSON 강제)
5. 요청: requests.get(..., timeout=10)
   → resp.raise_for_status() → resp.json()
6. 응답 경로:
   data["response"]["body"]["items"]
   를 pd.DataFrame 으로 변환
7. df[["dataTime","pm10Value","pm25Value"]].head()
   를 print

에러 처리:
- HTTP 오류 → 메시지 출력 후 종료
- items 가 없거나 빈 리스트면 안내 후 종료
- PUBLIC_DATA_KEY_DECODED 미설정이면 안내 후 종료

환경: Python 3.11, venv. 코드만, 한국어 주석 최소.

🎯 API 프롬프트의 결정적 디테일

  • 엔드포인트 URL 전체 를 적기 — AI 가 임의로 경로를 줄이거나 바꾸지 못하게
  • 쿼리 파라미터 7개를 키:값 쌍으로returnType: "json" 이 빠지면 AI 가 XML 응답을 받게 코드 작성
  • 응답 경로 data["response"]["body"]["items"] 명시 → 공공데이터 특유의 깊은 nesting 안전 통과
  • 인증키는 환경변수로 — 코드 안에 키를 박지 않는 보안 패턴

💡 다른 공공 API 응용 — 동일 프롬프트에서:
- 엔드포인트 URL 만 교체
- 파라미터 키 이름만 교체
- 응답 경로만 교체
하면 어떤 공공데이터든 30 줄 안에 호출.

📖 출처: ch08_prompts.md §3 — 공공데이터포털 정복.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

JSON 응답 가독성 — pprint / json.dumps indent 활용

📄 응답 모양

{
  "response": {
    "header": {
      "resultCode": "00",
      "resultMsg": "NORMAL_SERVICE"
    },
    "body": {
      "dataType": "JSON",
      "items": {
        "item": [
          {
            "baseDate": "20260501",
            "baseTime": "0600",
            "category": "TMP",
            "fcstValue": "18",
            "fcstDate": "20260502"
          },
          ...
        ]
      }
    }
  }
}

🔑 키 경로 읽기

  • 응답 = 3단 중첩
  • data["response"]["body"]["items"]["item"]레코드 리스트
  • 한 레코드는 dict → DataFrame 직접 변환

📌 resultCode "00" 이 정상. 자주 만나는 비정상 코드: - 30 NO_AUTHORIZED — 키가 잘못됨 - 22 LIMITED_NUMBER_OF_SERVICE_REQUESTS_EXCEEDS — 일일 한도 초과 - 33 DEADLINE_HAS_EXPIRED — 활용신청 만료

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

API 인증 4가지 — API Key / Bearer / OAuth / HMAC

🔑 1·2 — API Key / Bearer

API Key (가장 단순)

params = {"serviceKey": API_KEY}
requests.get(url, params=params)

Bearer Token (OAuth 후)

headers = {"Authorization": f"Bearer {TOKEN}"}
requests.get(url, headers=headers)

🔑 3·4 — OAuth 2.0 / HMAC

OAuth 2.0 — 3 단계: 1) 앱 등록 (Client ID + Secret) → 2) 사용자 동의 받아 인가 코드 발급 → 3) 코드를 토큰으로 교환해 Bearer 호출

HMAC (Hash-based Message Authentication Code) — 비밀키 + 요청 내용을 해시 → Authorization 헤더에 서명 동봉. 키 자체를 송신하지 않음 (보안 ↑↑, 거래소·결제 API)

방식 만나는 곳
API Key 공공데이터, OpenWeather
Bearer OpenAI, Claude, GitHub
OAuth Google, Naver Login
HMAC AWS, 거래소, 카카오페이
AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

API 에러 5종 — 메시지 해석과 대응

상태 의미 해결
401 Unauthorized 키 없음/오타 키 확인
403 Forbidden 키 있음 but 권한 부족 활용신청 승인 확인
429 Too Many Requests 한도 초과 sleep + 지수적 대기
500/502 Server Error 서버 일시 장애 retry
resultCode != "00" 응답 구조에 에러 resultMsg 출력
# 안전한 호출 + 메시지 점검
r = requests.get(url, params=params, timeout=10)
r.raise_for_status()             # HTTP 에러 → 예외
data = r.json()
header = data["response"]["header"]
if header["resultCode"] != "00":
    raise RuntimeError(header["resultMsg"])
PART D

금융 API
공식 vs 비공식

같은 데이터, 다른 합법성

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

금융 데이터 API — 5개 후보 비교 (공식 vs 비공식)

✅ 공식

  • DART OpenAPI (금감원 전자공시) — opendart.fss.or.kr
    기업 공시·재무
  • KRX 정보데이터시스템data.krx.co.kr
    거래소 공식 마켓 데이터
  • Yahoo Finance (yfinance)
    해외 주가
  • Alpha Vantage / Polygon
    해외 유료/무료

⚠️ 비공식 / 회색

  • 네이버 금융 페이지/숨은 JSON
  • 다음 금융 페이지
  • 인베스팅닷컴 페이지

🎯 권장

공식 우선 — 회차 7 윤리 파트와 직결. 비공식은 개인 학습용.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 별도첨부교재 외 보강 자료

전자공시 OpenAPI 빠른 시작 (OpenDART)

🔐 인증키 신청

  • 인증키 신청 주소: https://opendart.fss.or.kr/uss/umt/EgovMberInsertView.do
  • 개인 회원으로 신청 시, 가입과 동시에 이메일 인증 후 API 키 즉시 발급
  • OpenDART API 키 기준 일일 허용건수: 40,000건

📘 개발가이드

  • 개발가이드 주소: https://opendart.fss.or.kr/guide/main.do?apiGrpCd=DS001
  • 공시정보 API에서 아래 4가지를 바로 활용 가능
번호 API명 상세기능 개발가이드
1 공시검색 공시 유형별, 회사별, 날짜별 등 여러가지 조건으로 공시보고서 검색기능을 제공합니다. 바로가기
2 기업개황 DART에 등록되어있는 기업의 개황정보를 제공합니다. 바로가기
3 공시서류원본파일 공시보고서 원본파일을 제공합니다. 바로가기
4 고유번호 DART에 등록되어있는 공시대상회사의 고유번호,회사명,종목코드, 최근변경일자를 파일로 제공합니다. 바로가기

🎯 Session 5 적용 포인트: "공식 API 우선" 원칙에 맞는 대표 사례가 OpenDART.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 별도첨부교재 외 보강 자료

공시검색 개발가이드 (요약)

기본 정보

메서드 요청 URL 인코딩 출력포맷
GET https://opendart.fss.or.kr/api/list.json UTF-8 JSON
GET https://opendart.fss.or.kr/api/list.xml UTF-8 XML

요청 인자

요청키 명칭 타입 필수여부 값설명
crtfc_key API 인증키 STRING(40) Y 발급받은 인증키(40자리)
corp_code 고유번호 STRING(8) N 공시대상회사의 고유번호(8자리), 개발가이드 > 공시정보 > 고유번호 참고
bgn_de 시작일 STRING(8) N 검색시작 접수일자(YYYYMMDD), 기본값=end_de, corp_code 없으면 검색기간 3개월 제한
end_de 종료일 STRING(8) N 검색종료 접수일자(YYYYMMDD), 기본값=당일
last_reprt_at 최종보고서 검색여부 STRING(1) N Y or N, 기본값=N(정정이 있으면 최종정정만 검색)
pblntf_ty 공시유형 STRING(1) N A~J (A정기, B주요사항, C발행, D지분, E기타, F외부감사, G펀드, H자산유동화, I거래소, J공정위)
pblntf_detail_ty 공시상세유형 STRING(4) N 상세 유형 코드
corp_cls 법인구분 STRING(1) N Y(유가), K(코스닥), N(코넥스), E(기타), 미입력 시 전체
sort 정렬 STRING(4) N date(접수일), crp(회사명), rpt(보고서명), 기본값=date
sort_mth 정렬방법 STRING(4) N asc / desc, 기본값=desc
page_no 페이지 번호 STRING(5) N 기본값=1
page_count 페이지별 건수 STRING(3) N 1~100, 기본값=10, 최대=100

응답 결과

응답키 명칭 출력설명
status 에러 및 정보 코드 메시지 설명 참조
message 에러 및 정보 메시지 메시지 설명 참조
page_no 페이지 번호 페이지 번호
page_count 페이지별 건수 페이지별 건수
total_count 총 건수 총 건수
total_page 총 페이지 수 총 페이지 수
list 목록 공시 목록 배열
corp_cls 법인구분 Y/K/N/E
corp_name 종목명(법인명) 상장사 종목명 또는 법인명
corp_code 고유번호 8자리
stock_code 종목코드 6자리
report_nm 보고서명 공시구분+보고서명+기타정보(기재정정/첨부정정/첨부추가 등)
rcept_no 접수번호 14자리
flr_nm 공시 제출인명 공시 제출인명
rcept_dt 접수일자 YYYYMMDD
rm 비고 유/코/채/넥/공/연/정/철 조합

공시뷰어 연결 예시: https://dart.fss.or.kr/dsaf001/main.do?rcpNo=접수번호

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 별도첨부교재 외 보강 자료

예제 요청 URL

https://opendart.fss.or.kr/api/list.json?crtfc_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&bgn_de=20200117&end_de=20200117&corp_cls=Y&page_no=1&page_count=10

API 결과 (예시)

{
  "status": "000",
  "message": "정상",
  "page_no": 1,
  "page_count": 10,
  "total_count": 210,
  "total_page": 21,
  "list": [
    {
      "corp_code": "00120182",
      "corp_name": "NH투자증권",
      "stock_code": "005940",
      "corp_cls": "Y",
      "report_nm": "[첨부추가]일괄신고추가서류(파생결합증권-주가연계증권)",
      "rcept_no": "20200117000559",
      "flr_nm": "NH투자증권",
      "rcept_dt": "20200117",
      "rm": ""
    },
    {
      "corp_code": "00878915",
      "corp_name": "iM금융지주",
      "stock_code": "139130",
      "corp_cls": "Y",
      "report_nm": "소송등의판결ㆍ결정(자회사의 주요경영사항)",
      "rcept_no": "20200117800593",
      "flr_nm": "iM금융지주",
      "rcept_dt": "20200117",
      "rm": "유"
    },
    {
      "corp_code": "00120571",
      "corp_name": "롯데칠성음료",
      "stock_code": "005300",
      "corp_cls": "Y",
      "report_nm": "타법인주식및출자증권취득결정",
      "rcept_no": "20200117800584",
      "flr_nm": "롯데칠성음료",
      "rcept_dt": "20200117",
      "rm": "유정"
    }
    // ... (총 10건, 원문 예제와 동일 구조)
  ]
}

✅ 해석 포인트: status=000 이면 정상, list 배열에서 rcept_no 로 공시뷰어 URL을 바로 생성할 수 있습니다.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 별도첨부교재 외 보강 자료

고유번호 개발가이드 (corpCode.xml)

기본 정보

메서드 요청 URL 인코딩 출력포멧
GET https://opendart.fss.or.kr/api/corpCode.xml UTF-8 Zip FILE (binary)

요청 인자

요청키 명칭 타입 필수여부 값설명
crtfc_key API 인증키 STRING(40) Y 발급받은 인증키(40자리)

응답 결과

응답키 명칭 출력설명
status 에러 및 정보 코드 메시지 설명 참조
message 에러 및 정보 메시지 메시지 설명 참조
corp_code 고유번호 공시대상회사의 고유번호(8자리), ZIP 안 XML 정보
corp_name 정식명칭 정식회사명칭, ZIP 안 XML 정보
corp_eng_name 영문 정식명칭 영문정식회사명칭, ZIP 안 XML 정보
stock_code 종목코드 상장회사 주식 종목코드(6자리), ZIP 안 XML 정보
modify_date 최종변경일자 기업개황정보 최종변경일자(YYYYMMDD), ZIP 안 XML 정보

OpenAPI 테스트 주의사항

  • 출력포멧이 Zip FILE (binary) 인 경우 브라우저 테스트를 제공하지 않음
  • Chrome/Edge는 브라우저 특성상 zip이 아닌 xml로 다운로드될 수 있음
  • 이 경우 파일 확장자명을 zip으로 바꾸면 정상 확인 가능
  • 요청인자: API 인증키

🔗 개발가이드: https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS001&apiId=2019018

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

yfinance — 한 줄로 5년치 해외 주가

import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
from datetime import date

# 삼성전자 (005930.KS) — 2025-01-01 ~ 오늘
today = date.today().strftime("%Y-%m-%d")
df = yf.download("005930.KS", start="2025-01-01", end=today, auto_adjust=False)

# 1) 데이터 저장 (캔들 차트용 OHLCV 포함)
df.to_csv("output/price_data/samsung_2025_to_today.csv", encoding="utf-8-sig")

# 2) 가장 간단한 시계열 시각화 (종가)
close = df["Close"]
ax = close.plot(figsize=(10, 4), title="Samsung Electronics Close (2025~Today)")
ax.set_xlabel("Date")
ax.set_ylabel("KRW")
plt.tight_layout()
plt.savefig("output/charts/samsung_2025_to_today_close.png", dpi=160)
plt.show()

🎯 회차 8 시계열 분석의 베이스 데이터.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 별도첨부교재 외 보강 자료

yfinance 실행 결과 — 삼성전자 종가 시계열

삼성전자 2025년 1월 1일부터 현재까지의 주가 데이터 시각화

코드 실행 결과: samsung_2025_to_today_close.png

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 별도첨부교재 외 보강 자료

공시 이벤트 주석 차트

2026년 1월 1일부터 현재까지의 주가 데이터에 2026년 1월 한달간의 공시자료 오버레이

코드 실행 결과: samsung_2026_price_disclosures.png

PART E

LLM API
텍스트 분석 맛보기

댓글 1만 건 → 분류·감성·요약 = LLM 1~2분

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

전통 NLP vs LLM

🐢 전통 NLP

  • 형태소 분석 (한국어 문장을 단어/품사 단위로 쪼개기) 도구 설치
  • KoNLPy = 한국어 형태소 파이썬 패키지 / Mecab = 일본어 발 형태소 엔진
  • 사전 만들기, 룰 작성
  • 분류 모델 학습
  • 수일~수주 작업

🚀 LLM API

  • API 키 1줄
  • 프롬프트 1줄
  • 결과 JSON 1줄
  • 수분 작업

수동 NLP vs AI NLP

🎯 트레이드오프

LLM 은 빠르고 정확, but 비용 + 추론 비용 + 데이터 외부 송신.
회차 7 에서 데이터 외부 송신 위험 을 자세히.

비교 항목 전통 NLP LLM API
초기 셋업 수일~수주 수분
학습 데이터 직접 라벨링 필요 불필요
정확도 도메인 한정 범용 고정밀
비용 인건비·서버 API 호출당 과금
데이터 외부 송신 없음 (로컬) 외부 전송 발생
한국어 품질 형태소 정밀 문맥 우수
재현성 동일 입력 = 동일 출력 모델 업데이트로 변동

📌 언제 전통 NLP 가 더 나은가 — 의료·법률 등 외부 송신 금지 데이터, 비용 민감, 동일 입력 = 동일 출력 보장 필요한 연구.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API참고: examples/ch07/

Claude API 첫 호출 — 5줄로 댓글 감성 분류

💻 ① 호출 코드 (Anthropic Claude)

import os
from anthropic import Anthropic

# ANTHROPIC_API_KEY 환경변수 자동 사용
client = Anthropic()

text = (
    "배송이 빠르고 포장도 깔끔했어요. "
    "다만 제품 색이 사진과 좀 달라요."
)

resp = client.messages.create(
    model="claude-haiku-4-5",
    max_tokens=200,
    messages=[{
        "role": "user",
        "content": (
            "다음 리뷰를 분석해 JSON 으로 응답해.\n"
            '{"sentiment": '
            '"positive|negative|neutral", '
            '"topics": [...], '
            '"summary": "..."}\n\n'
            f"리뷰: {text}"
        ),
    }],
)
print(resp.content[0].text)

📤 ② 응답 (JSON)

{
  "sentiment": "neutral",
  "topics": ["배송", "포장", "색상"],
  "summary": "배송·포장 만족, 색상 불일치 불만"
}

🔑 코드 한눈에

  • Anthropic()ANTHROPIC_API_KEY 환경변수 자동 인식, 첫 줄로 클라이언트 준비
  • model="claude-haiku-4-5" — 가장 저렴·빠른 모델 (분류·요약에 충분)
  • max_tokens=200 — 응답 길이 상한 (비용 제어)
  • 프롬프트 안에 JSON 스키마 명시 → 결과 파싱 안정적
  • resp.content[0].text → 문자열 → json.loads() 로 파이썬 dict 변환

📌 회차 8 에서 1만 건 일괄 분류 + 비용 최적화 다룸.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

LLM 감성분석을 만든 프롬프트

💬 Antigravity / ChatGPT 입력 llm_sentiment.py

📋 prompt prompts/ch11_prompts.md 📄 example examples/ch11/llm_sentiment.py

Python 스크립트 llm_sentiment.py 를 만들어 줘.
목적: 한국어 리뷰 한 건의 감성·측면별 평가·
칭찬/불만 키워드를 OpenAI LLM 에 JSON 으로 요청해
dict 로 반환한다.

요구사항:
1. 라이브러리: openai, python-dotenv, 표준 json
2. .env 의 OPENAI_API_KEY 를 load_dotenv() 로 읽고
   OpenAI 클라이언트 생성
3. 함수 시그니처:
   sentiment_of(text: str) -> dict
4. 모델: gpt-4o-mini,
   response_format={"type": "json_object"}
5. 메시지 구성:
   - system: "한국어 리뷰의 감성을 분석한다.
              JSON 만 반환한다."
   - user: 리뷰 본문 + 다음 JSON 스키마로 응답:
     {
       "sentiment": "positive|negative|neutral",
       "score": -1.0 ~ 1.0 사이 실수,
       "aspects": {
         "delivery":"positive|negative|neutral|not_mentioned",
         "quality": "...",
         "price":   "...",
         "service": "..."
       },
       "praise":    [핵심 칭찬 키워드],
       "complaint": [핵심 불만 키워드]
     }
6. 반환:
   json.loads(resp.choices[0].message.content)
7. 하단에서 예시 리뷰로 호출 후 결과 print

에러 처리:
- JSON 파싱 실패 시 기본 구조 (모든 필드를
  neutral/not_mentioned, score=0.0,
  praise=[], complaint=[]) 로 반환
- API 실패 시 동일한 기본 구조 반환

환경: Python 3.11, venv. 코드만, 한국어 주석 최소.

🎯 LLM 프롬프트의 결정적 요소

  • JSON 스키마를 본문에 적시response_format={"type": "json_object"} 와 함께 사용해 응답 일관성 극대화
  • neutralnot_mentioned 분리 — "리뷰에 안 나온 측면" 과 "중립적으로 언급된 측면" 을 구분 → 통계가 정확해짐
  • score 는 실수 -1.0~1.0 — 카테고리 + 연속값 동시 제공 → 회귀 분석에 즉시 사용
  • JSON 파싱 실패 폴백 — LLM 이 가끔 깨진 JSON 을 줄 때 안전망

💡 연구 응용:
- 리뷰 → 의료 면담록·민원·인터뷰 전사
- aspects 4개 → 본인 연구 차원 (예: 감정/대응/만족)
으로 바꾸면 정성 데이터 코딩 자동화.

📖 출처: ch11_prompts.md §2 — 두 가지 접근 (감성사전 vs LLM).

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

OpenAI SDK vs Anthropic SDK — 동일 작업, 호출 방식 비교

from openai import OpenAI
client = OpenAI()  # OPENAI_API_KEY 환경변수

resp = client.chat.completions.create(
    model="gpt-4o-mini",
    response_format={"type": "json_object"},
    messages=[
        {"role": "system", "content": "리뷰를 JSON 으로 분석해."},
        {"role": "user", "content": text},
    ],
)
print(resp.choices[0].message.content)

두 SDK 비교

Anthropic (Claude) OpenAI (GPT)
강점 긴 컨텍스트(200K~1M 토큰), 분석·코드 정확성 생태계 광범위, JSON mode (응답을 항상 유효 JSON 으로 강제)
가격 Haiku 매우 저렴 gpt-4o-mini 매우 저렴
API key 변수 ANTHROPIC_API_KEY OPENAI_API_KEY

🎯 둘 다 .env 에 키 보관 — 코드에 직접 박지 말 것.

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

텍스트 분석 1만 건 = 얼마? (예시 비교 — 요금 수시 변동)

모델 입력 1M 토큰 출력 1M 토큰 1만 리뷰 추정
Claude Haiku 4.5 $1.00 $5.00 $1~$3 (사용량 따라)
Claude Sonnet 4.6 $3.00 $15.00 ~ $5 전후
Claude Opus 4.7 $5.00 $25.00 $8~$15 (요금 변동 가능)
GPT-4o-mini $0.15 $0.60 ~ $0.3
GPT-4o $2.50 $10.00 ~ $4

📌 2026-05 기준 — 강의일에 anthropic.com/pricing / openai.com/api/pricing 에서 재확인 필수

🎯 학위논문 가이드

첫 시도 — Haiku / 4o-mini. 정확도 부족하면 Sonnet 으로. Opus 는 샘플 1,000건 검증용.

PART F

미니 실습
두 API 직접 호출

공공데이터 + LLM 1회씩

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

미니 실습 — 공공데이터 + LLM 두 API 직접 호출

1단계 — 공공데이터

  • [ ] data.go.kr 가입 + 키 발급
  • [ ] 단기예보 또는 관광지 정보 1개 선택
  • [ ] Python 으로 호출 → DataFrame
  • [ ] CSV 저장 + df.head() 캡처

2단계 — LLM

  • [ ] OpenAI 또는 Claude API 키
  • [ ] 회차 3 책 데이터 로드
  • [ ] 책 제목 30개 → "장르 분류" 프롬프트
  • [ ] 결과 컬럼 추가한 CSV

제출

  • weather.csv (또는 tour.csv)
  • books_with_genre.csv
  • notebook.ipynb
PART G

API 우선
스크래핑은 마지막

AI를 활용한 공학적 연구 방법론·Session 5 · 동적 웹 페이지와 데이터 수집 전략출처: 바이브코딩 도서2Ch.5 실전 스크래핑 · Ch.8 공공데이터 API

오늘의 정리 8가지

  1. CSR / SSR / SPA / SSG — 첫 5분 판별
  2. AJAX, fetch — 동적 페이지의 실제 동작 방식
  3. API 우선 의사결정 트리 — 공식 → 숨은 JSON → HTML
  4. 공공데이터포털 = 한국 연구자의 1번 카드
  5. API 인증 4가지 — Key / Bearer / OAuth / HMAC
  6. 에러 5종 — 401/403/429/500/resultCode
  7. yfinance = 시계열 분석 진입로
  8. LLM API = NLP 작업 100배 단축

"스크래핑은 마지막. 먼저 API 가 있는지 본다."

1 / 36

목차 — Session 5

키보드 단축키 (뷰어)

네비게이션

다음 슬라이드 Space
이전 슬라이드 PgUp
처음 / 끝Home End
목차M

화면

전체화면F
테마 전환D
글자 크게 / 작게+ -
원래 크기 (100%)=
도움말 (열기/닫기)H ?
닫기 (모든 오버레이)Esc
강의 종료 (메인으로)Q

키보드 단축키 (강사)

네비게이션

다음 슬라이드 Space
이전 슬라이드 PgUp
처음 / 끝Home End
목차 (Menu)M
전체화면F

화면

테마 전환D
도움말 (열기/닫기)H ?
닫기 (모든 오버레이)Esc
툴바 펼치기 / 접기[ ]
강의 종료 (메인으로)Q

화면 확대

글자 크게 / 작게+ -
원래 크기 (100%)=
돋보기 (마우스 따라 2× 확대)V

발표자 도구 (PPT 호환)

화이트 화면W ,
블랙 화면B .
레이저 포인터L
펜 모드 ON/OFFP
펜 색상1 2 3 4
펜 자국 지우기 (현재 슬라이드)E
펜 — 마지막 스트로크 취소 (Undo)Z
펜 — 다시 (Redo)R
⏰ 쉬는시간 타이머T
📱 노트뷰 QR (휴대폰 동기화)N

PDF / 종료

PDF 저장 (슬라이드)Ctrl+P
강의 종료 (메인으로)Q X