""" Step 12: 현업 키워드 Excel → real_menus.json 업데이트 엑셀 파일(현업분류 시트)에서 키워드(현업) + 키워드(채널기획)를 SCREEN_NUM 기준으로 union/중복제거 후 real_menus.json keywords 필드 갱신. 실행: python scripts/12_update_keywords.py python scripts/12_update_keywords.py --input "경로/파일.xlsx" 출력: data/raw/real_menus.json (keywords 업데이트) data/updated_menu_ids.json (변경된 menu_id 목록 → 13번 스크립트에서 사용) """ import argparse import json import re from pathlib import Path import pandas as pd SCRIPT_DIR = Path(__file__).parent ROOT = SCRIPT_DIR.parent EXCEL_DEFAULT = Path(r"C:\Users\leeju\Documents\s#ai메뉴\Keyword_images\화면별 키워드 기재_요청안_최종.xlsx") REAL_MENUS_PATH = ROOT / "data" / "raw" / "real_menus.json" UPDATED_IDS_PATH = ROOT / "data" / "updated_menu_ids.json" def parse_keywords(cell_value: str) -> list: """쉼표·공백 구분 키워드 파싱 → 공백 제거 + 빈 문자열 제거""" if not cell_value or (isinstance(cell_value, float)): return [] # 쉼표 혹은 줄바꿈으로 분리 parts = re.split(r"[,\n]", str(cell_value)) return [p.strip() for p in parts if p.strip()] def main(): parser = argparse.ArgumentParser() parser.add_argument("--input", default=str(EXCEL_DEFAULT), help="엑셀 파일 경로") args = parser.parse_args() excel_path = Path(args.input) if not excel_path.exists(): print(f"[오류] 엑셀 파일 없음: {excel_path}") return # ── 1. 엑셀 현업분류 시트 읽기 ────────────────────────────────────── print(f"[1/4] 엑셀 읽기: {excel_path.name}") df = pd.read_excel(excel_path, sheet_name="현업분류", dtype=str, engine="openpyxl") biz_col = "키워드 (현업)" ch_col = "키워드 (채널기획)" # SCREEN_NUM → union 키워드 딕셔너리 screen_keywords: dict[str, list] = {} for _, row in df.iterrows(): snum = str(row.get("SCREEN_NUM", "")).strip() if not snum: continue kw_biz = parse_keywords(row.get(biz_col, "")) kw_ch = parse_keywords(row.get(ch_col, "")) # union: 현업 우선, 채널기획 추가 (중복 제거, 순서 보존) seen = set() merged = [] for kw in kw_biz + kw_ch: if kw not in seen: seen.add(kw) merged.append(kw) if merged: screen_keywords[snum] = merged print(f" 키워드 있는 SCREEN_NUM: {len(screen_keywords)}개") # ── 2. real_menus.json 읽기 ────────────────────────────────────────── print("[2/4] real_menus.json 읽기") menus = json.loads(REAL_MENUS_PATH.read_text(encoding="utf-8")) screen_to_menu = {str(m["screen_num"]): m for m in menus} # ── 3. keywords 업데이트 ────────────────────────────────────────────── print("[3/4] keywords 업데이트") updated_ids = [] no_match = [] for snum, new_kws in screen_keywords.items(): menu = screen_to_menu.get(snum) if menu is None: no_match.append(snum) continue old_kws = menu.get("keywords", []) if set(old_kws) != set(new_kws): menu["keywords"] = new_kws updated_ids.append(menu["menu_id"]) print(f" 업데이트: {len(updated_ids)}개 메뉴") print(f" 매칭 안된 SCREEN_NUM: {len(no_match)}개") if no_match[:5]: print(f" (샘플): {no_match[:5]}") # ── 4. 저장 ──────────────────────────────────────────────────────────── print("[4/4] 저장") REAL_MENUS_PATH.write_text( json.dumps(menus, ensure_ascii=False, indent=2), encoding="utf-8" ) UPDATED_IDS_PATH.parent.mkdir(parents=True, exist_ok=True) UPDATED_IDS_PATH.write_text( json.dumps(updated_ids, ensure_ascii=False, indent=2), encoding="utf-8" ) print(f"[완료] real_menus.json 갱신 ({len(updated_ids)}개)") print(f"[완료] updated_menu_ids.json 저장 → {UPDATED_IDS_PATH}") if __name__ == "__main__": main()