DB_JOB/작업파일/공공기관2/6.한국중부발전/_komipo_gnb.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

64 lines
2.6 KiB
Python

# -*- coding: utf-8 -*-
"""komipo GNB megamenu 권위트리 추출 → _komipo_tree.json (D,E,F,mnCd,type,url)"""
import json, re
from playwright.sync_api import sync_playwright
UA='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120 Safari/537.36'
BASE='https://www.komipo.co.kr'
with sync_playwright() as p:
b=p.chromium.launch(); pg=b.new_page(user_agent=UA,viewport={'width':1600,'height':2400})
pg.goto('https://www.komipo.co.kr/fr/realName/main.do?mnCd=FN011101',timeout=40000,wait_until='domcontentloaded'); pg.wait_for_timeout(3000)
rows=pg.evaluate(r"""()=>{
const nav=document.querySelector('nav');
const out=[];
for(const li1 of nav.querySelectorAll(':scope > ul > li')){
const D=(li1.querySelector(':scope>a')?.textContent||'').trim().replace(/\s+/g,' ');
// 중분류 = li.more (depth2 패널 안)
const mores=li1.querySelectorAll('li.more');
if(mores.length===0){
// li.more 없으면 depth3 직접 or 단일
for(const a of li1.querySelectorAll('ul.depth3 > li > a, ul > li > a')){
out.push({D,E:'',F:(a.textContent||'').trim().replace(/\s+/g,' '),href:a.getAttribute('href')||''});
}
continue;
}
for(const m of mores){
const E=(m.querySelector(':scope>p')?.textContent||'').trim().replace(/\s+/g,' ');
for(const a of m.querySelectorAll('ul.depth3 > li > a')){
out.push({D,E,F:(a.textContent||'').trim().replace(/\s+/g,' '),href:a.getAttribute('href')||''});
}
}
}
return out;
}""")
b.close()
def parse(href):
href=(href or '').strip()
m=re.search(r"goPage\('([A-Z]+)'\s*,\s*'([^']+)'", href)
if m:
typ=m.group(1); path=m.group(2)
url=path if path.startswith('http') else BASE+path
return typ, url
if href.startswith('http'):
return ('EXT' if 'komipo.co.kr' not in href else 'CONTENT'), href
if href.startswith('/'):
return 'CONTENT', BASE+href
return '', ''
tree=[]
for r in rows:
typ,url=parse(r['href'])
mn=''
m=re.search(r'mnCd=([A-Z0-9]+)',url)
if m: mn=m.group(1)
tree.append({'D':r['D'],'E':r['E'],'F':r['F'],'type':typ,'url':url,'mnCd':mn})
json.dump(tree,open('_komipo_tree.json','w',encoding='utf-8'),ensure_ascii=False,indent=1)
from collections import Counter
print('총 leaf:',len(tree))
print('대분류:',list(dict.fromkeys(t['D'] for t in tree)))
print('type분포:',dict(Counter(t['type'] for t in tree)))
# 대분류별 중분류
for D in dict.fromkeys(t['D'] for t in tree):
es=list(dict.fromkeys(t['E'] for t in tree if t['D']==D))
print('',D,'중분류:',es)