#!/usr/bin/env python3 """ update-csv-gu-content.py 강남언니 badges + procedures → clinic_registry_working.csv 에 컬럼 추가 """ import csv, re, os BASE = os.path.join(os.path.dirname(__file__), '..', 'data', 'clinic-registry') # ── 스크래핑 결과 (hospital_id → badges, procedures) ──────────────────────── GU_CONTENT = { 23: (["수술실 CCTV","마취과 전문의 상주","여성 의사 진료","분야별 공동 진료","시술 후 관리","의료진 실명 공개","환자 숙박 정보 제공","전용 휴식 공간","입원 시설","응급 대응 체계","미용 의료 시술 진료","야간진료"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","필러","보톡스","리프팅","모발이식"]), 189: (["수술실 CCTV","마취과 전문의 상주","분야별 공동 진료","의료진 실명 공개","야간진료","여성 의사 진료","응급 대응 체계","시술 후 관리","입원 시설","전용 휴식 공간"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","필러","보톡스","피부리프팅","기타"]), 257: (["수술실 CCTV","시술 후 관리","의료진 실명 공개","여성 의사 진료","분야별 공동 진료","입원 시설","전용 휴식 공간","환자 숙박 정보 제공","야간진료","마취과 전문의 상주","응급 대응 체계"], ["양악수술","안면윤곽","눈/코성형","가슴성형","리프팅","피부클리닉","쁘띠성형","치과"]), 62: (["분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","입원 시설","마취과 전문의 상주","의료진 실명 공개","성형외과 전문의 진료","여성 의사 진료","미용 의료 시술 진료","환자 숙박 정보 제공","역에서 도보 5분","학회 활동 의사"], ["피부","코성형","눈성형","보톡스","필러","리프팅","가슴성형","지방성형"]), 2500: (["고객평가우수병원","분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","수술실 CCTV","여성 의사 진료","마취과 전문의 상주","야간진료","의료진 실명 공개"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","기타","모발이식","리프팅","보톡스","필러"]), 729: (["수술실 CCTV","입원 시설","의료진 실명 공개","전용 휴식 공간","시술 후 관리","응급 대응 체계","분야별 공동 진료"], ["코성형","안면윤곽","양악","눈성형","지방성형","필러","보톡스","가슴성형","리프팅","피부"]), 215: (["분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","수술실 CCTV","입원 시설","마취과 전문의 상주","야간진료","의료진 실명 공개"], ["눈성형","코성형","안면윤곽/양악","가슴성형","리프팅","기타","지방성형","피부","보톡스","필러"]), 926: (["수술실 CCTV","시술 후 관리","전용 휴식 공간","미용 의료 시술 진료","의료진 실명 공개"], ["눈성형","코성형","가슴성형","지방성형","필러","보톡스","리프팅"]), 938: (["분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","수술실 CCTV","여성 의사 진료","입원 시설","마취과 전문의 상주","의료진 실명 공개"], ["눈성형","코성형","가슴성형","지방성형","리프팅","필러","보톡스","안면윤곽/양악","피부"]), 2186: (["분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","환자 숙박 정보 제공","수술실 CCTV","여성 의사 진료","입원 시설","마취과 전문의 상주","야간진료","의료진 실명 공개"], ["눈성형","코성형","지방성형","가슴성형","안면윤곽/양악","리프팅"]), 250: (["분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","환자 숙박 정보 제공","수술실 CCTV","여성 의사 진료","입원 시설","마취과 전문의 상주","야간진료","의료진 실명 공개"], ["눈성형","코성형","지방성형","필러","보톡스","리프팅","가슴성형","안면윤곽/양악","모발이식","기타","피부"]), 3004: (["분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","여성 의사 진료","입원 시설","마취과 전문의 상주","야간진료","의료진 실명 공개","학회 활동 의사","미용 의료 시술 진료","역에서 도보 5분","성형외과 전문의 진료"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","필러","보톡스","리프팅","피부","기타"]), 139: (["마취과 전문의 상주","분야별 공동 진료","시술 후 관리","의료진 실명 공개","야간진료","여성 의사 진료","응급 대응 체계","입원 시설","전용 휴식 공간","미용 의료 시술 진료","성형외과 전문의 진료","학회 활동 의사"], ["피부","코성형","눈성형","보톡스","필러","리프팅","지방성형","기타"]), 141: (["시술 후 관리","전용 휴식 공간","수술실 CCTV","입원 시설","마취과 전문의 상주","의료진 실명 공개"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","필러","보톡스","리프팅","피부"]), 55: (["분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","환자 숙박 정보 제공","입원 시설","마취과 전문의 상주","의료진 실명 공개"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","필러","보톡스","리프팅","제모","치아","모발이식","한방"]), 116: (["고객평가우수병원","분야별 공동 진료","시술 후 관리","전용 휴식 공간","수술실 CCTV","입원 시설","마취과 전문의 상주","의료진 실명 공개"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","리프팅","필러","보톡스","기타"]), 248: (["수술실 CCTV","응급 대응 체계","시술 후 관리","전용 휴식 공간","입원 시설","마취과 전문의 상주","야간진료","의료진 실명 공개","분야별 공동 진료"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","필러","보톡스","리프팅","기타"]), 331: (["야간진료","시술 후 관리","전용 휴식 공간","여성 의사 진료"], ["안면윤곽","양악","지방성형","필러","보톡스","피부","리프팅","기타"]), 1449: (["시술 후 관리","의료진 실명 공개","전용 휴식 공간","응급 대응 체계"], ["코성형","눈성형","지방성형","리프팅","기타"]), 2196: (["응급 대응 체계","시술 후 관리","전용 휴식 공간","입원 시설","의료진 실명 공개","역에서 도보 5분","성형외과 전문의 진료","학회 활동 의사"], ["피부코성형","눈성형","보톡스","모발이식","리프팅","지방성형","가슴성형"]), 398: (["고객평가우수병원","분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","환자 숙박 정보 제공","여성 의사 진료","미용 의료 시술 진료","입원 시설","마취과 전문의 상주","야간진료","의료진 실명 공개","역에서 도보 5분","학회 활동 의사","성형외과 전문의 진료"], ["안면윤곽","양악수술","눈성형","코성형","가슴성형","체형성형","줄기세포","쁘띠성형","안티에이징","지방성형","필러","보톡스","리프팅","모발이식","기타"]), 1515: (["입원 시설","의료진 실명 공개","전용 휴식 공간","응급 대응 체계","시술 후 관리"], ["피부코성형","눈성형","안면윤곽/양악","보톡스","필러","리프팅","제모","지방성형","가슴성형","치아","모발이식","한방"]), 213: (["분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","수술실 CCTV","입원 시설","마취과 전문의 상주","야간진료","의료진 실명 공개"], ["눈성형","코성형","가슴성형","보톡스","리프팅","필러","기타","안면윤곽/양악","지방성형"]), 4154: (["수술실 CCTV","마취과 전문의 상주","시술 후 관리","의료진 실명 공개","전용 휴식 공간","응급 대응 체계","여성 의사 진료"], ["가슴성형","보톡스","필러","기타","지방성형","치아","리프팅","모발이식","한방"]), 623: (["고객평가우수병원","입원 시설","전용 휴식 공간","시술 후 관리"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","필러","보톡스","리프팅","기타"]), 2122: (["고객평가우수병원","시술 후 관리","전용 휴식 공간","입원 시설","야간진료","의료진 실명 공개","응급 대응 체계","분야별 공동 진료","성형외과 전문의 진료","환자 숙박 정보 제공","미용 의료 시술 진료","역에서 도보 5분","학회 활동 의사","마취과 전문의 상주"], ["눈성형","코성형","지방성형","필러","보톡스","리프팅","기타","가슴성형"]), 6597: (["고객평가우수병원","분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","입원 시설","마취과 전문의 상주","의료진 실명 공개"], ["얼굴성형","동안성형","채형성형","줄기세포성형","피부코성형","눈성형","안면윤곽/양악","보톡스","필러","리프팅","가슴성형","지방성형","기타"]), 166: (["수술실 CCTV","여성 의사 진료","입원 시설","마취과 전문의 상주","의료진 실명 공개","시술 후 관리","전용 휴식 공간","응급 대응 체계","분야별 공동 진료"], ["눈성형","코성형","가슴성형","지방성형","리프팅","안면윤곽/양악","보톡스","필러","기타"]), 108: (["수술실 CCTV","마취과 전문의 상주","응급 대응 체계","의료진 실명 공개","분야별 공동 진료","시술 후 관리","야간진료","입원 시설","전용 휴식 공간"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","필러","보톡스","리프팅","기타"]), 69: (["고객평가우수병원"], ["리프팅","필러","보톡스","눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","피부","기타","모발이식"]), 660: (["수술실 CCTV","응급 대응 체계","시술 후 관리","전용 휴식 공간","야간진료","의료진 실명 공개"], ["눈성형","코성형","지방성형","필러","보톡스","리프팅"]), 4244: (["여성 의사 진료","의료진 실명 공개","미용 의료 시술 진료","역에서 도보 5분","학회 활동 의사","성형외과 전문의 진료","분야별 공동 진료","전용 휴식 공간","시술 후 관리"], ["피부","코성형","눈성형","보톡스","필러","리프팅","가슴성형","지방성형","기타","제모"]), 300: (["수술실 CCTV","의료진 실명 공개","응급 대응 체계","시술 후 관리","야간진료","여성 의사 진료","전용 휴식 공간","분야별 공동 진료"], ["눈성형","코성형","가슴성형","지방성형","보톡스","피부리프팅","필러","제모","기타","리프팅","모발이식","한방"]), 563: (["응급 대응 체계","마취과 전문의 상주","입원 시설","시술 후 관리","전용 휴식 공간"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","필러","보톡스","리프팅"]), 2991: (["응급 대응 체계","시술 후 관리","전용 휴식 공간","의료진 실명 공개","야간진료","미용 의료 시술 진료","여성 의사 진료","역에서 도보 5분","학회 활동 의사","성형외과 전문의 진료","분야별 공동 진료"], ["눈성형","코성형","지방성형","필러","보톡스","리프팅","제모","가슴성형","치아","모발이식","한방"]), 58: (["수술실 CCTV","응급 대응 체계","시술 후 관리","전용 휴식 공간","입원 시설","마취과 전문의 상주","의료진 실명 공개","분야별 공동 진료"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","필러","보톡스","리프팅","기타"]), 54: (["시술 후 관리","입원 시설","전용 휴식 공간","의료진 실명 공개","응급 대응 체계","마취과 전문의 상주","분야별 공동 진료","야간진료","역에서 도보 5분","성형외과 전문의 진료","학회 활동 의사"], ["피부코성형","눈성형","보톡스","필러","모발이식","리프팅","가슴성형","지방성형","기타"]), 1181: (["고객평가우수병원","분야별 공동 진료","미용 의료 시술 진료","시술 후 관리","야간진료","전용 휴식 공간","여성 의사 진료","응급 대응 체계","의료진 실명 공개","역에서 도보 5분","성형외과 전문의 진료"], ["코성형","눈성형","지방성형","필러","보톡스","피부리프팅","기타"]), 3000: (["수술실 CCTV","시술 후 관리","전용 휴식 공간","응급 대응 체계","의료진 실명 공개"], ["눈성형","코성형","지방성형","리프팅","필러","보톡스","기타","제모","가슴성형","치아","모발이식","한방"]), 66: (["고객평가우수병원","분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","입원 시설","의료진 실명 공개","성형외과 전문의 진료","야간진료","역에서 도보 5분"], ["눈성형","코성형","지방성형","리프팅","보톡스","필러"]), 4749: (["시술 후 관리","야간진료","여성 의사 진료","미용 의료 시술 진료","전용 휴식 공간"], ["피부보톡스","필러","제모","리프팅","지방성형","기타"]), 5500: (["의료진 실명 공개","응급 대응 체계","시술 후 관리","야간진료","입원 시설","전용 휴식 공간"], ["안면윤곽","양악","코성형","눈성형","피부","보톡스","필러","리프팅","지방성형","제모","가슴성형","치아","모발이식"]), 431: (["의료진 실명 공개","응급 대응 체계","시술 후 관리","전용 휴식 공간","역에서 도보 5분","성형외과 전문의 진료","미용 의료 시술 진료"], ["눈성형","코성형","안면윤곽/양악","가슴성형","지방성형","리프팅","필러","보톡스"]), 5870: (["시술 후 관리","전용 휴식 공간","입원 시설","야간진료","의료진 실명 공개"], ["코성형","눈성형","보톡스","필러","리프팅","지방성형","피부"]), 2052: (["시술 후 관리","전용 휴식 공간","수술실 CCTV","의료진 실명 공개"], ["눈성형","코성형","지방성형","필러","보톡스","리프팅","모발이식"]), 4459: (["여성 의사 진료","야간진료","미용 의료 시술 진료"], ["피부보톡스","필러","리프팅","제모","기타","지방성형","가슴성형","치아","모발이식","한방"]), 339: (["분야별 공동 진료","시술 후 관리","전용 휴식 공간","야간진료","의료진 실명 공개","성형외과 전문의 진료"], ["눈성형","코성형","안면윤곽/양악","필러","리프팅","보톡스","지방성형","기타","가슴성형"]), 912: (["시술 후 관리","전용 휴식 공간","수술실 CCTV","의료진 실명 공개"], ["눈성형","코성형","지방성형","필러","기타"]), 1265: (["의료진 실명 공개","응급 대응 체계","분야별 공동 진료","시술 후 관리","입원 시설","전용 휴식 공간","성형외과 전문의 진료"], ["피부코성형","눈성형","보톡스","필러","리프팅","가슴성형","지방성형"]), 839: (["수술실 CCTV","마취과 전문의 상주","시술 후 관리","의료진 실명 공개","응급 대응 체계","입원 시설","전용 휴식 공간"], ["가슴성형","지방성형","필러","보톡스","리프팅","피부","제모","기타","치아","모발이식","한방"]), 5554: (["고객평가우수병원","의료진 실명 공개","응급 대응 체계","시술 후 관리","전용 휴식 공간","수술실 CCTV"], ["코성형","눈성형","리프팅","가슴성형","안면윤곽/양악","지방성형","기타","치아","모발이식","한방"]), 4212: (["수술실 CCTV","의료진 실명 공개","응급 대응 체계","마취과 전문의 상주","시술 후 관리","전용 휴식 공간","여성 의사 진료"], ["코재수술","코제거","코성형","재건 중점 진료"]), 6680: (["응급 대응 체계","시술 후 관리","입원 시설","의료진 실명 공개"], ["리프팅","가슴성형","눈성형","지방성형","치아","모발이식","한방"]), 369: (["분야별 공동 진료","시술 후 관리","전용 휴식 공간","입원 시설","마취과 전문의 상주","야간진료"], ["눈성형","코성형","지방성형","필러","보톡스","리프팅","기타"]), 6204: (["고객평가우수병원"], ["눈성형","코성형","보톡스","필러","가슴성형","지방성형","피부"]), 3569: (["고객평가우수병원","분야별 공동 진료","응급 대응 체계","시술 후 관리","전용 휴식 공간","입원 시설","마취과 전문의 상주","의료진 실명 공개","성형외과 전문의 진료","역에서 도보 5분"], ["안면윤곽","양악","가슴성형","눈성형","코성형","리프팅","지방성형"]), 1178: (["야간진료","의료진 실명 공개","시술 후 관리","미용 의료 시술 진료","응급 대응 체계","전용 휴식 공간","분야별 공동 진료"], ["필러","보톡스","리프팅","피부","기타"]), 3429: (["응급 대응 체계","시술 후 관리","전용 휴식 공간","입원 시설","의료진 실명 공개","환자 숙박 정보 제공","분야별 공동 진료","야간진료"], ["입술성형","귀성형","인중축소","안면윤곽","가슴성형","눈성형","코성형","리프팅","지방성형","기타"]), 413: (["고객평가우수병원","시술 후 관리","의료진 실명 공개"], ["눈성형","코성형","지방성형","가슴성형"]), 5636: (["고객평가우수병원"], ["코성형","눈성형","안면윤곽/양악","보톡스","필러","리프팅","가슴성형","지방성형","제모","기타","치아","모발이식","한방"]), } def extract_id(url): m = re.search(r'/hospitals/(\d+)', url or '') return int(m.group(1)) if m else None def lookup(url): hid = extract_id(url) if hid and hid in GU_CONTENT: badges, procs = GU_CONTENT[hid] return ';'.join(badges), ';'.join(procs) return '', '' # ── clinic_registry_working.csv ────────────────────────────────────────────── reg_path = os.path.join(BASE, 'clinic_registry_working.csv') with open(reg_path, newline='', encoding='utf-8-sig') as f: reader = csv.DictReader(f) fields = list(reader.fieldnames) rows = list(reader) # gangnam_unni_reviews 뒤에 삽입 (중복 방지) insert_after = 'gangnam_unni_reviews' if 'gangnam_unni_badges' not in fields: idx = fields.index(insert_after) + 1 if insert_after in fields else len(fields) fields[idx:idx] = ['gangnam_unni_badges', 'gangnam_unni_procedures'] updated = 0 for row in rows: badges_str, procs_str = lookup(row.get('gangnam_unni_url', '')) row.setdefault('gangnam_unni_badges', badges_str) row.setdefault('gangnam_unni_procedures', procs_str) if badges_str: updated += 1 with open(reg_path, 'w', newline='', encoding='utf-8-sig') as f: writer = csv.DictWriter(f, fieldnames=fields, extrasaction='ignore') writer.writeheader() writer.writerows(rows) print(f'✅ clinic_registry_working.csv — {updated}개 병원 badges/procedures 추가') print(f' 총 컬럼: {len(fields)}개') print() print('샘플 (첫 3개):') for r in rows[:3]: print(f" {r['hospital_name']:<18} badges={len(r.get('gangnam_unni_badges','').split(';'))}개 procs={len(r.get('gangnam_unni_procedures','').split(';'))}개")