# -*- coding: utf-8 -*- import openpyxl,ssl,urllib.request,re,time,shutil 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'} def fetch(u): return urllib.request.urlopen(urllib.request.Request(u,headers=HDR),timeout=25,context=ctx).read() TOT1=re.compile(r'총\s*게시물\s*(\d[\d,]*)') TOT2=re.compile(r'전체\s*(\d[\d,]*)\s*건') TOT3=re.compile(r'(\d[\d,]*)\s*건') CENTER_SITE=re.compile(r'kipf\.re\.kr/(cpem|soe|gafsc|cfa|projections|ctla|panel|beps|gmac|sesim)/',re.I) SRC='한국조세재정연구원.xlsx' shutil.copy(SRC,'한국조세재정연구원_backup_LM전.xlsx') wb=openpyxl.load_workbook(SRC);ws=wb.active def getM(u): try: soup=BeautifulSoup(fetch(u),'html.parser') except Exception as e: return None,'ERR' txt=soup.get_text(' ',strip=True) m=TOT1.search(txt) if m: return int(m.group(1).replace(',','')),'총게시물' m=TOT2.search(txt) if m: return int(m.group(1).replace(',','')),'전체N건' # first "N 건" but avoid huge year etc -> take first reasonable m=TOT3.search(txt) if m: return int(m.group(1).replace(',','')),'N건' return 0,'none' site=board=page=0 for r in range(3,ws.max_row+1): if all(ws.cell(r,c).value in (None,'') for c in range(2,16)): continue K=str(ws.cell(r,11).value or '');L=ws.cell(r,12).value if CENTER_SITE.search(K) or 'soelms.kipf.re.kr' in K: ws.cell(r,12).value='사이트' for c in (13,14,15,16,17): ws.cell(r,c).value=None site+=1; continue if L=='사이트': site+=1; continue if L=='게시판': M,how=getM(K) ws.cell(r,13).value=M if M==0: ws.cell(r,14).value='없음' board+=1 print(f'r{r} {(ws.cell(r,6).value or ws.cell(r,5).value or "")[:18]:18} M={M} ({how})') time.sleep(0.4) else: page+=1 print(f'\n게시판 {board} · 사이트 {site} · 페이지 {page}') wb.save(SRC); print('saved')