# -*- coding: utf-8 -*- # 프리랜서2 신규 기준 읽기전용 재감사 — 머신체크 가능 위반만. import os, glob, io, sys, re import openpyxl sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') BASE = r'D:\01.프로젝트\DB수집\작업파일' N_OK = {'어문','이미지','영상','오디오','글꼴','3D','기타','없음'} # 열: L=12 M=13 N=14 O=15 P=16 Q=17, S(비고)=19 def audit(path): wb = openpyxl.load_workbook(path, read_only=True, data_only=True) ws = wb.active rows = [r for r in ws.iter_rows(min_row=3, values_only=True)] res = {'rows':0,'P페이지':[], 'N위반':{}, '사이트오염':[], '게시판M0N':[], '로그인':[], '페이지M≠1':0} for i,row in enumerate(rows, start=3): def g(col): return row[col-1] if len(row)>=col else None B=g(2) if not isinstance(B,int): continue res['rows']+=1 L=str(g(12) or '').strip(); M=g(13); N=str(g(14) or '').strip() O=g(15); P=str(g(16) or '').strip(); Q=g(17); S=str(g(19) or '') # P=페이지 if P=='페이지': res['P페이지'].append(i) # N 8종 위반 if N and L!='사이트': for tok in N.split(','): tok=tok.strip() if tok and tok not in N_OK: res['N위반'].setdefault(tok,[]).append(i) # 사이트 오염 if L=='사이트' and any(x not in (None,'') for x in (M,g(14),O,g(16),Q)): res['사이트오염'].append(i) # 게시판 M0 & N≠없음 if L=='게시판' and (M in (0,'0')) and N not in ('없음',''): res['게시판M0N'].append(i) # 페이지 M≠1 (인페이지탭 가능 → 참고) if L=='페이지' and M not in (1,'1',None): res['페이지M≠1']+=1 # 로그인 흔적 if re.search(r'로그인|본인인증', S): res['로그인'].append(i) wb.close() return res def collect(): files=[] for p in glob.glob(os.path.join(BASE,'광역_사이트맵','*','*','*.xlsx')): b=os.path.basename(p) if 'backup' in b or b.startswith('_'): continue files.append(p) for p in glob.glob(os.path.join(BASE,'교육청_사이트맵','*','*.xlsx')): b=os.path.basename(p) if 'backup' in b or b.startswith('_'): continue files.append(p) return sorted(files) def main(): files=collect() print('감사 대상 파일:',len(files)) total={'P페이지':0,'N위반':0,'사이트오염':0,'게시판M0N':0,'로그인':0,'페이지M≠1':0} badN_global={} flagged=[] for p in files: nm=os.path.basename(p).replace('.xlsx','') try: r=audit(p) except Exception as e: print('ERR',nm,e); continue nP=len(r['P페이지']); nN=sum(len(v) for v in r['N위반'].values()) nC=len(r['사이트오염']); nM0=len(r['게시판M0N']); nLg=len(r['로그인']); nPM=r['페이지M≠1'] total['P페이지']+=nP; total['N위반']+=nN; total['사이트오염']+=nC total['게시판M0N']+=nM0; total['로그인']+=nLg; total['페이지M≠1']+=nPM for k,v in r['N위반'].items(): badN_global[k]=badN_global.get(k,0)+len(v) if nP or nN or nC or nM0 or nLg: flagged.append((nm,r['rows'],nP,nN,r['N위반'],nC,nM0,nLg,nPM)) print('\n=== 위반 있는 기관 ===') print('%-22s %5s %6s %6s %-18s %5s %5s %5s'%('기관','행','P페이지','N위반','(N위반값)','사이트','M0N','로그인')) for (nm,rows,nP,nN,badN,nC,nM0,nLg,nPM) in flagged: bn=','.join('%s×%d'%(k,len(v)) for k,v in badN.items()) if badN else '' print('%-22s %5d %6d %6d %-18s %5d %5d %5d'%(nm,rows,nP,nN,bn[:18],nC,nM0,nLg)) print('\n=== 합계 ===', total) print('N위반 값 분포:', badN_global) print('참고: 페이지M≠1 합계 %d (인페이지탭 정상 포함 가능)'%total['페이지M≠1']) main()