DB_JOB/작업파일/완료_1-2주차/2주차/검토_리포트/extract_data.py
hehihoho3 df16c98366 백업: DB수집 전체 스냅샷 (공공기관2 정리 전)
공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:15:40 +09:00

87 lines
2.8 KiB
Python

"""엑셀에서 사이트별 메뉴 구조 데이터 추출."""
import sys, io, json
from collections import defaultdict
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
import openpyxl
XLSX = r"D:\01.프로젝트\DB수집\2주차\공공저작물 실태조사_프리랜서_260528_장영익 검토.xlsx"
OUT = r"D:\01.프로젝트\DB수집\2주차\검토_리포트\excel_data.json"
wb = openpyxl.load_workbook(XLSX, data_only=True)
ws = wb['Sheet1']
# 컬럼 매핑 (행2 헤더 기준)
# B(2)=순번, C(3)=사이트명, D(4)=메뉴명, E(5)=카테고리(대), F(6)=중,
# G(7)=소, H(8)=소A, I(9)=소B, J(10)=소C, K(11)=URL, L(12)=게시판형태,
# M(13)=수량, N(14)=저작물유형, O(15)=공공누리부착, P(16)=마크부착위치,
# Q(17)=마크하이퍼링크
sites = defaultdict(list)
# D, E, F는 병합된 셀이라 위쪽 행에서 값 받음 — forward-fill 필요
last_D, last_E, last_F = None, None, None
last_site = None
for r in range(3, ws.max_row + 1):
seq = ws.cell(row=r, column=2).value
site = ws.cell(row=r, column=3).value
D = ws.cell(row=r, column=4).value
E = ws.cell(row=r, column=5).value
F = ws.cell(row=r, column=6).value
G = ws.cell(row=r, column=7).value
H = ws.cell(row=r, column=8).value
I = ws.cell(row=r, column=9).value
J = ws.cell(row=r, column=10).value
K = ws.cell(row=r, column=11).value
L = ws.cell(row=r, column=12).value
S = ws.cell(row=r, column=19).value
# forward-fill
if site: last_site = site
if D is not None: last_D = D
if E is not None: last_E = E
if F is not None: last_F = F
# 사이트가 바뀌면 D/E/F 캐시 리셋
if site and site != last_site:
last_D, last_E, last_F = None, None, None
last_site = site
sites[last_site or '?'].append({
'row': r,
'seq': seq,
'D': last_D if D is None else D,
'E': last_E if E is None else E,
'F': last_F if F is None else F,
'G': G,
'H': H,
'I': I,
'J': J,
'K': K,
'L': L,
'S': S,
'D_raw': D, 'E_raw': E, 'F_raw': F, # 병합 흔적 보존
})
# 사이트명에 '사이트명' 같이 헤더 흘러들어간 행 제외
filtered = {k: v for k, v in sites.items() if k and k != '사이트명'}
# datetime 등 직렬화 불가 객체 처리
def safe(x):
if x is None or isinstance(x, (str, int, float, bool)):
return x
return str(x)
cleaned = {}
for site, rows in filtered.items():
cleaned[site] = [{k: safe(v) for k, v in r.items()} for r in rows]
with open(OUT, 'w', encoding='utf-8') as f:
json.dump(cleaned, f, ensure_ascii=False, indent=2)
print('사이트별 행 수:')
for s, rows in cleaned.items():
print(f' {s}: {len(rows)}')
print(f'\n저장: {OUT}')