공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
62 lines
2.8 KiB
Python
62 lines
2.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
import openpyxl, time, json, re, sys, ssl, urllib.request
|
|
from urllib.parse import urljoin, urlparse, parse_qs
|
|
from bs4 import BeautifulSoup
|
|
ctx=ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE
|
|
HDR={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/124 Safari/537.36'}
|
|
BASE='https://www.komipo.co.kr'
|
|
def fetch(u): return urllib.request.urlopen(urllib.request.Request(u,headers=HDR),timeout=25,context=ctx).read()
|
|
|
|
wb=openpyxl.load_workbook('한국중부발전.xlsx');ws=wb.active
|
|
# existing url set (normalized: path + mnCd value)
|
|
def norm(u):
|
|
if not u: return ''
|
|
p=urlparse(str(u)); q=parse_qs(p.query)
|
|
mn=q.get('mnCd',[''])[0]
|
|
return p.path.rstrip('/')+'|'+mn
|
|
existing=set()
|
|
for r in range(3,ws.max_row+1):
|
|
k=ws.cell(r,11).value
|
|
if k: existing.add(norm(k))
|
|
|
|
# candidate pages at Excel row >=89, komipo host
|
|
cands=[]
|
|
for r in range(89,ws.max_row+1):
|
|
k=ws.cell(r,11).value
|
|
if not k or 'komipo.co.kr' not in str(k): continue
|
|
cands.append((r,ws.cell(r,2).value,str(k)))
|
|
print('후보',len(cands),file=sys.stderr)
|
|
|
|
found={}
|
|
for r,b,k in cands:
|
|
try:
|
|
soup=BeautifulSoup(fetch(k),'html.parser')
|
|
except Exception as e:
|
|
print('ERR',r,str(e)[:50],file=sys.stderr); time.sleep(0.5); continue
|
|
uls=soup.find_all('ul', class_=lambda c: c and 'tab_link' in ' '.join(c if isinstance(c,list) else [c]))
|
|
for ul in uls:
|
|
tabs=[]
|
|
for li in ul.find_all('li', recursive=False):
|
|
a=li.find('a')
|
|
if not a: continue
|
|
tabs.append({'label':a.get_text(strip=True),'href':a.get('href',''),'current':'current' in (li.get('class') or [])})
|
|
if len(tabs)<2: continue
|
|
# classify same vs diff url
|
|
bases=set()
|
|
for t in tabs:
|
|
h=t['href']; full=urljoin(BASE+'/',h) if h.startswith('/') else h
|
|
bases.add(norm(full) if 'komipo' in full else full.split('#')[0])
|
|
samurl = len(bases)==1
|
|
# already expanded? all tab urls present in sheet
|
|
tnorms=[norm(urljoin(BASE+'/',t['href'])) for t in tabs]
|
|
missing=[tn for tn in tnorms if tn not in existing]
|
|
found[r]={'b':b,'url':k,'tabs':tabs,'same_url':samurl,'missing_count':len(missing),'n_tabs':len(tabs)}
|
|
time.sleep(0.7)
|
|
json.dump(found,open('scan2.json','w',encoding='utf-8'),ensure_ascii=False,indent=1)
|
|
for r,v in sorted(found.items(),key=lambda x:int(x[0])):
|
|
flag='SAME-URL(M=%d)'%v['n_tabs'] if v['same_url'] else ('DIFF missing=%d/%d'%(v['missing_count'],v['n_tabs']))
|
|
star=' <== NEW' if (v['same_url'] or v['missing_count']>0) else ' (already)'
|
|
print(f"r{r} b{v['b']} [{flag}]{star} {v['url'][:50]}")
|
|
for t in v['tabs']:
|
|
print(f" [{'*' if t['current'] else ' '}] {t['label']!r} {t['href'][:55]}")
|