# -*- coding: utf-8 -*- """진안 엑셀행 57~끝 본문 렌더 스크린샷(이미지 검출용). 페이지=#sub_contents/게시판=첫글. _nshots2/""" import glob, os, re, json, urllib.request from collections import Counter import openpyxl from playwright.sync_api import sync_playwright DIR = os.path.dirname(__file__) SHOT = os.path.join(DIR, '_nshots2') os.makedirs(SHOT, exist_ok=True) HDR = {'User-Agent': 'Mozilla/5.0'} 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 '' 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 targets = [] for r in range(57, ws.max_row + 1): # 엑셀행 57부터 L = ws.cell(r, 12).value if L in ('페이지', '게시판'): targets.append({'r': r, 'L': L, 'M': ws.cell(r, 13).value, 'N': str(ws.cell(r, 14).value or ''), 'lab': ws.cell(r, 7).value or ws.cell(r, 6).value or ws.cell(r, 5).value or '', 'K': str(ws.cell(r, 11).value or '')}) 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 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 with sync_playwright() as pw: br = pw.chromium.launch() pg = br.new_page(viewport={'width': 1100, 'height': 1500}) for i, tg in enumerate(targets): out = os.path.join(SHOT, f"r{tg['r']}.png") if os.path.exists(out): continue url = tg['K'] if tg['L'] == '게시판' and tg['M'] not in (0, None): pu = first_post(tg['K']) if pu: url = pu try: pg.goto(url, timeout=25000, wait_until='domcontentloaded') pg.wait_for_timeout(1100) el = None for sel in ['#sub_contents', '#contents']: el = pg.query_selector(sel) if el: break (el or pg).screenshot(path=out) except Exception as e: print('ERR', tg['r'], str(e)[:50], flush=True) if (i + 1) % 30 == 0: print(f'... {i+1}/{len(targets)}', flush=True) br.close() json.dump(targets, open(os.path.join(DIR, '_ntargets2.json'), 'w', encoding='utf-8'), ensure_ascii=False, indent=0) print('DONE', len(targets))