77 lines
2.6 KiB
Python
77 lines
2.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""KCOPA 공공누리(O) 부착 전수 라이브 재스캔 (2026-06-24)
|
|
페이지=본문 opentype0N / 게시판=상세 view.do 샘플 union. 시트 O 대조."""
|
|
import openpyxl, requests, re, sys
|
|
from urllib.parse import urljoin
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
requests.packages.urllib3.disable_warnings()
|
|
H={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
|
|
S=requests.Session(); S.headers.update(H); S.verify=False
|
|
|
|
def get(u):
|
|
try:
|
|
return S.get(u,timeout=25).text
|
|
except Exception:
|
|
return ''
|
|
|
|
def marks(html):
|
|
return set(int(d) for d in re.findall(r'opentype0?([1-4])', html, re.I))
|
|
|
|
def view_links(html, base):
|
|
h=html.replace('&','&')
|
|
raw=re.findall(r'(view\.do\?article_seq=\d+)', h)+re.findall(r'(view\.do\?ntt_id=\d+)', h)
|
|
seen=[]
|
|
for v in raw:
|
|
if v not in seen: seen.append(v)
|
|
return [urljoin(base, v) for v in seen[:12]]
|
|
|
|
def scan_row(args):
|
|
r,label,L,url=args
|
|
if not url: return (r,label,L,set(),'NO_URL')
|
|
html=get(url)
|
|
if L=='게시판' and 'list.do' in url:
|
|
vl=view_links(html, url)
|
|
agg=set()
|
|
if vl:
|
|
for d in vl:
|
|
agg|=marks(get(d))
|
|
return (r,label,L,agg,f'bbs {len(vl)}상세')
|
|
# program/gallery board: mark may be on list/contents itself
|
|
agg=marks(html)
|
|
return (r,label,L,agg,'list직접')
|
|
else:
|
|
return (r,label,L,marks(html),'page본문')
|
|
|
|
def main():
|
|
wb=openpyxl.load_workbook('한국저작권보호원.xlsx'); ws=wb.active
|
|
rows=[]
|
|
for r in range(3,98):
|
|
b=ws.cell(r,2).value
|
|
L=ws.cell(r,12).value
|
|
O=ws.cell(r,15).value or '미부착'
|
|
hl=ws.cell(r,11).hyperlink
|
|
url=hl.target if hl else ws.cell(r,11).value
|
|
f=ws.cell(r,6).value or ws.cell(r,5).value
|
|
rows.append((r,f,L,url,O))
|
|
args=[(r,f,L,url) for (r,f,L,url,O) in rows]
|
|
res={}
|
|
with ThreadPoolExecutor(max_workers=8) as ex:
|
|
for out in ex.map(scan_row, args):
|
|
res[out[0]]=out
|
|
def parse_O(o):
|
|
return set(int(d) for d in re.findall(r'([1-4])유형', o or ''))
|
|
print('ROW | 라벨 | 시트O | 검출 | 판정 | 방법')
|
|
mismatch=[]
|
|
for (r,f,L,url,O) in rows:
|
|
_,_,_,det,how=res[r]
|
|
sheet=parse_O(O)
|
|
ok = (det==sheet)
|
|
tag='OK' if ok else 'MISMATCH'
|
|
if not ok: mismatch.append((r,f,O,sorted(det),how))
|
|
if (det or sheet or not ok):
|
|
print(f'{r:>3} | {str(f)[:28]:28s} | {O:12s} | {sorted(det)} | {tag} | {how}')
|
|
print('\n=== MISMATCH', len(mismatch),'건 ===')
|
|
for m in mismatch: print(m)
|
|
|
|
main()
|