DB_JOB/작업파일/공공기관2/_hf_contab_scan.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

71 lines
2.7 KiB
Python

# -*- coding: utf-8 -*-
"""주택금융 전 페이지에서 con0X/row 탭(별도 .do 서브페이지 탭) 스캔.
시트에 없는 탭멤버 리포트."""
import sys, io, os, glob, re, json
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
import openpyxl
from playwright.sync_api import sync_playwright
BASE = r"D:\01.프로젝트\DB수집\작업파일\공공기관2"
fp = [x for x in glob.glob(os.path.join(BASE, "5.*", "*.xlsx")) if "_backup" not in x and "~$" not in x][0]
ws = openpyxl.load_workbook(fp, read_only=True).active
def norm(u):
u = re.sub(r'https?://[^/]+', '', str(u or ''))
u = u.split('?')[0]
return u.rstrip('/')
existing = set()
pages = []
seen = set()
for r in range(3, ws.max_row+1):
k = ws.cell(r,11).value
if k and 'hf.go.kr' in str(k):
existing.add(norm(k))
n = norm(k)
if '.do' in n and n not in seen:
seen.add(n); pages.append(str(k).split('?')[0])
print(f"시트 hf페이지 {len(pages)}개, 기존URL {len(existing)}")
TAB_JS = """
() => {
const groups=[];
document.querySelectorAll('ul[class*=con0], ul.tab, ul[class*=tab], .tab-wrap ul, .sub-tab ul').forEach(ul=>{
const items=[...ul.querySelectorAll(':scope>li>a')].map(a=>({t:(a.textContent||'').trim().replace(/\\s+/g,' '), h:a.href})).filter(x=>x.t && /\\.do/.test(x.h) && !/#/.test(x.h));
if(items.length>=2){
const cls=String(ul.className);
groups.push({cls, items});
}
});
return groups;
}
"""
found = {}
with sync_playwright() as p:
br=p.chromium.launch(headless=True)
pg=br.new_context(ignore_https_errors=True,viewport={'width':1600,'height':1000}).new_page()
for i,u in enumerate(pages):
try:
pg.goto(u, wait_until='domcontentloaded', timeout=15000); pg.wait_for_timeout(400)
gs=pg.evaluate(TAB_JS)
except Exception:
gs=[]
for g in gs:
key=frozenset(norm(it['h']) for it in g['items'])
if key not in found:
found[key]=g['items']
if (i+1)%40==0: print(f" ...{i+1}/{len(pages)} (그룹 {len(found)})")
br.close()
print(f"\n탭 그룹 {len(found)}개:")
missing_groups=[]
for key,items in found.items():
miss=[it for it in items if norm(it['h']) not in existing]
mark='✅전부있음' if not miss else f'⚠️누락 {len(miss)}'
labs=', '.join(it['t'][:12] for it in items)
print(f" [{mark}] {labs}")
if miss: missing_groups.append({'items':items,'missing':miss})
json.dump(missing_groups, open(os.path.join(BASE,'_hf_missing_tabs.json'),'w',encoding='utf-8'), ensure_ascii=False, indent=1)
print(f"\n누락 그룹 {len(missing_groups)}개 → _hf_missing_tabs.json")