# -*- coding: utf-8 -*- """57+ 어문 행 HTML 콘텐츠이미지 검출 → 이미지 후보 추림. 페이지=#sub_contents/게시판=첫글본문.""" import glob, os, re, json, urllib.request, time from collections import Counter import openpyxl HDR = {'User-Agent': 'Mozilla/5.0'} DIR = os.path.dirname(__file__) EXCL = re.compile(r'(/upload_data/popup/|/banner/|BBS_0000160|menu_qrcode|img_opentype|btn_|icon_|/common/|blank|spacer|bullet|move\.png|no_?img|qrcode|sns_|facebook|insta|/share|loading)', re.I) INC = re.compile(r'/upload_data/(board_data|editor|cms|fckeditor|se2)/|/2018/images/[^"]*/contents/|/editor/', re.I) def get(u): try: return urllib.request.urlopen(urllib.request.Request(u.replace(' ', '%20'), headers=HDR), timeout=20).read().decode('utf-8', 'replace') except Exception: return '' def content_imgs(h, bid=None): i = h.find('id="sub_contents"') foot = h.find('id="footer', i) if i >= 0 else -1 c = h[i:foot] if i >= 0 and foot > i else h res = [] for s in re.findall(r']+src="([^"]+)"', c): if EXCL.search(s): continue if bid and ('board_data/' + bid) in s: res.append(s) elif INC.search(s) and (not re.search(r'board_data/BBS_', s) or (bid and bid in s)): res.append(s) return res def first_post(k): h = get(k).replace('&', '&') menu = re.search(r'menuCd=([A-Z0-9_]+)', k) menu = menu.group(1) if menu else '' vb = [b for b in re.findall(r'view\.jinan\?[^"\']*?boardId=([A-Z0-9_]+)[^"\']*?dataSid=', h) if b != 'BBS_0000157'] if not vb: return None, None bid = Counter(vb).most_common(1)[0][0] lh = get(f'http://www.jinan.go.kr/board/list.jinan?boardId={bid}&menuCd={menu}&paging=ok&startPage=1').replace('&', '&') vs = [v for v in re.findall(r'view\.jinan\?([^"\']+)', lh) if f'boardId={bid}' in v and 'dataSid=' in v] return ('http://www.jinan.go.kr/board/view.jinan?' + vs[0].replace(' ', '%20')) if vs else None, bid t = glob.glob(os.path.join(DIR, '*.xlsx')) t = [p for p in t if 'backup' not in p and not os.path.basename(p).startswith(('~$', '_'))][0] ws = openpyxl.load_workbook(t).active rows = [r for r in range(57, ws.max_row + 1) if ws.cell(r, 12).value in ('페이지', '게시판') and '이미지' not in str(ws.cell(r, 14).value or '') and str(ws.cell(r, 14).value or '') not in ('사이트', '없음')] cand = [] for r in rows: time.sleep(0.15) k = str(ws.cell(r, 11).value) if ws.cell(r, 12).value == '게시판' and ws.cell(r, 13).value not in (0, None): pu, bid = first_post(k) imgs = content_imgs(get(pu), bid) if pu else [] else: imgs = content_imgs(get(k)) if imgs: cand.append({'row': r, 'L': ws.cell(r, 12).value, 'lab': ws.cell(r, 7).value or ws.cell(r, 6).value or '', 'n': len(imgs), 'sample': imgs[0][:60]}) print(f"r{r}[{ws.cell(r,12).value}] {ws.cell(r,7).value or ws.cell(r,6).value}: img{len(imgs)} {imgs[0][:50]}", flush=True) json.dump(cand, open(os.path.join(DIR, '_imgcand.json'), 'w', encoding='utf-8'), ensure_ascii=False, indent=0) print('후보', len(cand), '/', len(rows))