# -*- coding: utf-8 -*- import openpyxl, urllib.request, ssl, re, json, time from urllib.parse import quote, urlsplit, urlunsplit from concurrent.futures import ThreadPoolExecutor ctx=ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE def enc(u): p=urlsplit(u); return urlunsplit((p.scheme,p.netloc,p.path,quote(p.query,safe='=&'),p.fragment)) def get(u): for _ in range(4): try: req=urllib.request.Request(enc(u),headers={'User-Agent':'Mozilla/5.0'}) return urllib.request.urlopen(req,context=ctx,timeout=20).read().decode('utf-8','replace') except Exception: time.sleep(0.6) return None def board_count(h): nums=[] for tr in re.findall(r']*>(.*?)', h, re.S): if 'href' not in tr: continue tds=re.findall(r']*>(.*?)', tr, re.S) if not tds: continue first=re.sub(r'<[^>]+>','',tds[0]).strip().replace(',','') if first.isdigit(): nums.append(int(first)) return (max(nums) if nums else 0), len(nums) # empty board: has board thead (제목/작성일) but 0 data rows def is_board_shell(h): return bool(re.search(r']*>\s*제목', h)) and ('hidden-md-down' in h) FN='제주특별자치도_서귀포시.xlsx' wb=openpyxl.load_workbook(FN); ws=wb.active rowsX=[] for r in range(78, ws.max_row+1): L=ws.cell(r,12).value; url=ws.cell(r,11).value if L=='사이트' or not url or 'seogwipo.go.kr' not in url: continue rowsX.append((r,url,L,ws.cell(r,13).value)) def task(item): r,url,L,M=item h=get(url) if not h: return r,None cnt,gl=board_count(h) shell=is_board_shell(h) if cnt==0 else False return r,(cnt,gl,shell) res={} with ThreadPoolExecutor(max_workers=6) as ex: for r,d in ex.map(task, rowsX): res[r]=d changes=[] for r,url,L,M in rowsX: d=res.get(r) if d is None: changes.append((r,'FETCHFAIL',L,M,None)); continue cnt,gl,shell=d if cnt>0: newL='게시판'; newM=cnt if L!=newL or M!=newM: ws.cell(r,12).value=newL; ws.cell(r,13).value=newM # if was page with N missing-> keep N; ensure O baseline if site? keep changes.append((r, ('L:%s→게시판 '%L if L!='게시판' else '')+'M:%s→%d'%(M,newM), L,M,newM)) elif shell and L!='게시판': ws.cell(r,12).value='게시판'; ws.cell(r,13).value=0; ws.cell(r,14).value='없음' changes.append((r,'L:%s→게시판(빈) M0 N없음'%L,L,M,0)) wb.save(FN) print('대상 %d행 | 변경 %d행'%(len(rowsX), len(changes))) import openpyxl as o w2=o.load_workbook(FN); s2=w2.active for r,desc,oL,oM,nM in changes: lbl=[s2.cell(r,c).value for c in (6,7,8) if s2.cell(r,c).value] print(' r%d %s | %s'%(r,(lbl[-1] if lbl else '')[:20], desc))