"""고용노동부 — 사이트맵 vs 엑셀 비교.""" import sys, io, json sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') with open(r'D:\01.프로젝트\DB수집\2주차\검토_리포트\excel_data.json', encoding='utf-8') as f: excel = json.load(f) with open(r'D:\01.프로젝트\DB수집\2주차\검토_리포트\moel_sitemap_tree.json', encoding='utf-8') as f: tree = json.load(f) moel_excel = excel['고용노동부'] flat = tree['flat'] # 트리에서 (path, url) 매핑 만들기 tree_urls = {} # url -> path tree_paths = set() # tuple(path) for node in flat: path = tuple(node['path']) tree_paths.add(path) if node.get('absUrl'): tree_urls[node['absUrl']] = path # URL 정규화 — 쿼리 파라미터 제거 비교용 def norm(u): if not u: return u return u.split('?')[0].rstrip('/') tree_urls_norm = {norm(k): v for k, v in tree_urls.items()} print(f'엑셀 행 수 (고용노동부): {len(moel_excel)}') print(f'사이트맵 노드 수: {len(flat)}') print(f'사이트맵 URL 있는 노드: {len(tree_urls)}') # 엑셀 각 행의 D/E/F/G/H/I/J path를 만들어서 트리와 비교 mismatches = [] # 불일치 matched = 0 no_url_in_tree = 0 # URL이 트리에 없음 url_path_diff = 0 # URL은 있는데 path가 다름 # 엑셀의 외부링크 행은 제외 (S='외부링크' or URL이 다른 도메인) for r in moel_excel: K = r['K'] if not K or r['S'] == '외부링크' or 'moel.go.kr' not in (K if isinstance(K, str) else ''): continue # 엑셀 path 구성: D, E, F, G, H, I, J 순으로 비어있지 않은 값들 excel_path = tuple(v for v in [r['D'], r['E'], r['F'], r['G'], r['H'], r['I'], r['J']] if v) # 트리에서 같은 URL 찾기 nu = norm(K) if nu in tree_urls_norm: tree_path = tree_urls_norm[nu] if tree_path == excel_path: matched += 1 else: url_path_diff += 1 mismatches.append({ 'type': 'PATH_DIFF', 'row': r['row'], 'url': K, 'excel_path': list(excel_path), 'tree_path': list(tree_path), }) else: no_url_in_tree += 1 mismatches.append({ 'type': 'URL_NOT_IN_SITEMAP', 'row': r['row'], 'url': K, 'excel_path': list(excel_path), }) print(f'\n=== 매칭 결과 ===') print(f' 완전 일치: {matched}') print(f' URL 동일, path 다름: {url_path_diff}') print(f' URL이 사이트맵에 없음: {no_url_in_tree}') # 사이트맵에는 있는데 엑셀에 없는 항목 — 누락 excel_urls = set() for r in moel_excel: K = r['K'] if K and isinstance(K, str): excel_urls.add(norm(K)) missing_in_excel = [] for url, path in tree_urls_norm.items(): if url not in excel_urls: missing_in_excel.append({'url': url, 'tree_path': list(path)}) print(f'\n=== 사이트맵에는 있는데 엑셀에 없는 URL (잠재적 누락) ===') print(f' 개수: {len(missing_in_excel)}') # D열 매칭 (대분류 일치 여부) excel_D_set = set(r['D'] for r in moel_excel if r['D']) tree_D_set = set(tree['roots']) print(f'\n=== D열 (메뉴명) 비교 ===') print(f' 엑셀: {sorted(excel_D_set)}') print(f' 사이트맵: {sorted(tree_D_set)}') print(f' 엑셀에 있는데 사이트맵에 없음: {excel_D_set - tree_D_set}') print(f' 사이트맵에 있는데 엑셀에 없음: {tree_D_set - excel_D_set}') # 결과 저장 result = { 'site': '고용노동부', 'excel_rows': len(moel_excel), 'tree_nodes': len(flat), 'matched': matched, 'url_path_diff': url_path_diff, 'url_not_in_sitemap': no_url_in_tree, 'missing_in_excel': len(missing_in_excel), 'D_excel': sorted(excel_D_set), 'D_tree': sorted(tree_D_set), 'D_excel_only': sorted(excel_D_set - tree_D_set), 'D_tree_only': sorted(tree_D_set - excel_D_set), 'mismatches_sample': mismatches[:30], 'missing_in_excel_sample': missing_in_excel[:20], } with open(r'D:\01.프로젝트\DB수집\2주차\검토_리포트\moel_compare.json', 'w', encoding='utf-8') as f: json.dump(result, f, ensure_ascii=False, indent=2) print('\nsaved moel_compare.json')