공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
71 lines
2.7 KiB
Python
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")
|