# -*- coding: utf-8 -*- """정보공개(info포털 #gnb) 하위 + 전국사업소 13본부를 _gnb\1.json에 보완.""" import sys, io, json sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') from playwright.sync_api import sync_playwright GNB = r"D:\01.프로젝트\DB수집\작업파일\공공기관2\_gnb\1.json" data = json.load(open(GNB, encoding='utf-8')) rows = data['gnb'] # 전국사업소 13본부 (GNB 기존값) offices = [ ("서울본부","2100000"),("대구경북본부","3500000"),("광주전남본부","4500000"), ("경기본부","5500000"),("강원본부","6500000"),("전북본부","7500000"), ("제주본부","8500000"),("부산울산본부","3100000"),("인천본부","4100000"), ("대전세종충남본부","5100000"),("경기북부본부","6100000"),("충북본부","7100000"), ("경남본부","8100000"), ] INFO_JS = """ () => { const cont=document.querySelector('#gnb'); if(!cont) return []; function labelA(li){for(const a of li.querySelectorAll('a,button')){let p=a.parentElement,ins=false;while(p&&p!==li){if(p.tagName==='UL'){ins=true;break;}p=p.parentElement;}if(!ins&&(a.textContent||'').trim())return a;}return null;} function topUls(el){return [...el.querySelectorAll('ul')].filter(ul=>{let p=ul.parentElement;while(p&&p!==el){if(p.tagName==='UL')return false;p=p.parentElement;}return true;});} const out=[]; function walk(ul,depth){[...ul.children].filter(li=>li.tagName==='LI').forEach(li=>{const a=labelA(li);if(a){const l=(a.textContent||'').trim().replace(/\\s+/g,' ');let h=a.tagName==='A'?(a.href||''):'';if(l)out.push({depth,label:l,href:h});}topUls(li).forEach(s=>walk(s,depth+1));});} (cont.tagName==='UL'?[cont]:topUls(cont)).forEach(u=>walk(u,1)); return out; } """ # 새 rows 구성: 기존 rows를 돌며 전국사업소 depth1 뒤에 본부 삽입, 정보공개 depth1 뒤에 info트리 삽입 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() pg.goto('https://www.kesco.or.kr/info/main.do', wait_until='domcontentloaded', timeout=30000); pg.wait_for_timeout(2000) info=pg.evaluate(INFO_JS) br.close() print('정보공개 info #gnb', len(info), '항목') new=[] for r in rows: new.append(r) if r['depth']==1 and r['label']=='전국사업소': for nm,code in offices: new.append({'depth':2,'label':nm,'href':f'https://www.kesco.or.kr/office/main.do?bonbu_code={code}'}) if r['depth']==1 and r['label']=='정보공개': for it in info: new.append({'depth':1+it['depth'], 'label':it['label'], 'href':it['href']}) data['gnb']=new json.dump(data, open(GNB,'w',encoding='utf-8'), ensure_ascii=False, indent=1) print('총', len(new), '행 (정보공개+전국사업소 보완)')