공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
30 lines
1.2 KiB
Python
30 lines
1.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""스캔 결과(json)에서 도메인+컨테이너클래스 시그니처로 사이트를 벤더 클러스터링."""
|
|
import json, sys, re
|
|
from collections import defaultdict
|
|
sys.stdout.reconfigure(encoding='utf-8')
|
|
R = json.load(open(r'D:\01.프로젝트\DB수집\작업파일\_temp\_tab_rescan_report.json', encoding='utf-8'))
|
|
|
|
def vendor_sig(r):
|
|
cls = r.get('classes') or []
|
|
# 클래스명에서 페이지별 suffix 제거(tab_sub01_02 → tab_sub)
|
|
norm = []
|
|
for c in cls:
|
|
c2 = re.sub(r'_(sub|cont|page)?[\d_]+', '', c).strip()
|
|
norm.append(c2)
|
|
base = norm[0] if norm else '(무탭/기타)'
|
|
return base
|
|
|
|
clusters = defaultdict(list)
|
|
for r in R:
|
|
if not r.get('ok'):
|
|
clusters['(에러)'].append(r['name']); continue
|
|
if not r.get('groups'):
|
|
clusters['(탭0)'].append(r['name']); continue
|
|
clusters[vendor_sig(r)].append(f"{r['name']}({r['prov'][:2]}{'·검수완료' if r['inspected'] else ''})")
|
|
|
|
print('=== 벤더(컨테이너 클래스) 클러스터 ===')
|
|
for sig, sites in sorted(clusters.items(), key=lambda x:-len(x[1])):
|
|
print(f'\n[{sig}] — {len(sites)}곳')
|
|
print(' ', ', '.join(sites))
|