공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
55 lines
2.8 KiB
Python
55 lines
2.8 KiB
Python
# -*- 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), '행 (정보공개+전국사업소 보완)')
|