DB_JOB/작업파일/완료/광역_사이트맵/전북특별자치도/3.김제시/_N검증.py
hehihoho3 df16c98366 백업: DB수집 전체 스냅샷 (공공기관2 정리 전)
공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:15:40 +09:00

110 lines
4.8 KiB
Python

# -*- coding: utf-8 -*-
"""김제 게시판 N 재판정: 게시물 상세 본문(bbs_view) 안의 실제 콘텐츠 이미지 유무 검사.
콘텐츠 이미지 = /upload_data/ (에디터 본문삽입). 제외 = /images/common/(로고·opentype마크)·이모티콘·아이콘.
첨부파일(bbs_file 영역)은 본문 이미지로 치지 않음(별도).
출력: 보드별 표본 게시물수 / 본문이미지 있는 게시물수 / 샘플 경로.
"""
import urllib.request, ssl, re, html as ht, sys, json
ctx = ssl.create_default_context(); ctx.check_hostname=False; ctx.verify_mode=ssl.CERT_NONE
BASE='https://www.gimje.go.kr'
def get(url):
req=urllib.request.Request(url, headers={'User-Agent':'Mozilla/5.0'})
return urllib.request.urlopen(req,context=ctx,timeout=25).read().decode('utf-8','replace')
def view_links(menucd):
d=get(f'{BASE}/index.gimje?menuCd={menucd}')
raw=re.findall(r'href="(/board/view\.gimje\?[^"]+)"', d)
out=[]
for l in raw:
l=ht.unescape(l)
if l not in out: out.append(l)
return out, d
def list_thumbs(listhtml):
"""목록 페이지의 콘텐츠 썸네일(갤러리/자료형 신호). 사이트공통 팝업·common 제외."""
imgs=re.findall(r'<img[^>]+src="([^"]*upload_data[^"]*)"', listhtml)
out=[]
for i in imgs:
i=i.strip()
if 'BBS_0000269' in i: continue # 사이트공통 팝업 공지
if '/images/common/' in i.lower() or 'opentype' in i.lower(): continue
out.append(i)
return out
def body_imgs(det):
s=det.find('bbs_view')
if s<0: s=det.find('bbs_con')
if s<0: return None, [] # 본문 컨테이너 못찾음
ends=[p for p in (det.find('bbs_file',s), det.find('bbs_btn',s), det.find('bbs_navi',s), det.find('bbs_paging',s)) if p>0]
e=min(ends) if ends else s+12000
seg=det[s:e]
imgs=re.findall(r'<img[^>]+src="([^"]+)"', seg)
content=[]
for i in imgs:
i=i.strip()
low=i.lower()
if '/images/common/' in low: continue
if 'opentype' in low: continue
if any(k in low for k in ('icon','emoticon','blank.','spacer','btn_','/common/','logo')): continue
if '/upload_data/' in low or '/editor' in low or 'board_data' in low or '/se2/' in low:
content.append(i)
return len(imgs), content
def scan(menucd, nmax=10):
links, listhtml = view_links(menucd)
thumbs=list_thumbs(listhtml)
links=links[:nmax]
posts=[]
for l in links:
try:
det=get(BASE+l)
except Exception as ex:
posts.append({'link':l,'err':str(ex)}); continue
total, cont = body_imgs(det)
posts.append({'link':l,'total_img':total,'content_img':cont})
nwith=sum(1 for p in posts if p.get('content_img'))
return {'checked':len(posts),'with_img':nwith,'thumbs':len(thumbs),
'samples':[p['content_img'][0] for p in posts if p.get('content_img')][:3],
'thumb_samples':thumbs[:3],'posts':posts}
def targets_from_xlsx(path, rfrom=162, only_image=True):
import openpyxl
wb=openpyxl.load_workbook(path); ws=wb.active
last=max(r for r in range(3,ws.max_row+1) if ws.cell(r,2).value not in (None,''))
out=[]
for r in range(rfrom,last+1):
L=ws.cell(r,12).value; N=str(ws.cell(r,14).value or '')
if not (L and '게시판' in str(L)): continue
if only_image and '이미지' not in N: continue
url=str(ws.cell(r,11).value or '')
m=re.search(r'menuCd=([A-Za-z0-9_]+)', url)
if not m: continue
parts=[ws.cell(r,c).value for c in range(4,11)]
label=' > '.join(str(p) for p in parts if p not in (None,''))
out.append([r, m.group(1), label, N])
return out
if __name__=='__main__':
if sys.argv[1].startswith('--'):
mode=sys.argv[1]
oi = (mode=='--suspects') # --suspects: 이미지표시만 / --allboards: 전체 게시판
targets=[[r,m,l] for r,m,l,n in targets_from_xlsx('전북특별자치도_김제시.xlsx', only_image=oi)]
else:
targets=json.loads(sys.argv[1]) # [[row,menucd,label], ...]
for row, menucd, label in targets:
try:
r=scan(menucd)
gallery = r['thumbs']>=2 # 목록 썸네일 2개 이상 = 갤러리/자료형
body = r['with_img']>0 # 본문 인라인 사진
verdict='어문,이미지' if (gallery or body) else '어문'
mode = ('갤러리' if gallery else '')+('+본문' if body else '') or '없음'
print(f"{row} | {label[:30]} | 표본{r['checked']} 본문img{r['with_img']} 목록썸네일{r['thumbs']} [{mode}] → {verdict}")
for s in r['thumb_samples'][:1]:
print(f" 썸네일: {s[:72]}")
for s in r['samples'][:1]:
print(f" 본문img: {s[:72]}")
except Exception as ex:
print(f"{row} | {label[:30]} | ERR {ex}")