# -*- coding: utf-8 -*- # 청양 133~385 본문탭(ul.slave_tab 등) 전수 스캔 import openpyxl, json, io, sys, time from urllib.parse import urljoin, urlparse from playwright.sync_api import sync_playwright sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8') F=r'D:\01.프로젝트\DB수집\작업파일\광역_사이트맵\충청남도\13.청양군\충청남도_청양군.xlsx' wb=openpyxl.load_workbook(F); ws=wb.active rows=[] for r in range(133,386): b=ws.cell(r,2).value if b is None: continue hl=ws.cell(r,11).hyperlink; u=(hl.target if hl else ws.cell(r,11).value) or '' L=ws.cell(r,12).value lab=str(ws.cell(r,6).value or ws.cell(r,7).value or ws.cell(r,5).value or '') rows.append((r,b,lab,u,L)) print('대상',len(rows),flush=True) # 본문 탭: slave_tab/basic_tab/tab류 ul. LNB제외 위해 #contents/.contents 내부만 JS=r'''()=>{ let main=document.querySelector('#contents,.contents,.sub_contents,.sub_container,.contents_area,#content,.content_area,#container'); if(!main) main=document.body; const out=[]; const uls=main.querySelectorAll('ul[class*=slave_tab],ul[class*=basic_tab],ul.tab,ul[class*=tab_],ul[class*=_tab],.tab_menu ul,.content_tab ul,.tab_wrap ul'); uls.forEach(ul=>{ // LNB류 배제 if(ul.closest('.lnb,.snb,.gnb,nav,.lnb_depth2__list,.lnb_depth3__list')) return; const cls=ul.className||''; const items=[]; ul.querySelectorAll(':scope > li > a').forEach(a=>{ items.push({t:(a.innerText||'').trim().replace(/\s+/g,' '), href:a.getAttribute('href'), blank:(a.getAttribute('target')||'')==='_blank' || /새창/.test(a.getAttribute('title')||''), on:/\bon\b|active|current/.test(a.parentElement.className||'')}); }); if(items.length) out.push({cls,n:items.length,items}); }); return out; }''' def nav(pg,u): for _ in range(2): try: pg.goto(u,wait_until='domcontentloaded',timeout=20000); pg.wait_for_timeout(1300); return True except Exception: time.sleep(1) return False res={} with sync_playwright() as p: b=p.chromium.launch(); pg=b.new_page(viewport={'width':1300,'height':2200}); pg.set_default_timeout(20000) for r,bn,lab,u,L in rows: if not u.startswith('http'): continue try: if nav(pg,u): tabs=pg.evaluate(JS) # 의미있는 탭(2개+)만 tabs=[t for t in tabs if t['n']>=2] if tabs: res[r]={'b':bn,'lab':lab,'u':u,'L':L,'tabs':tabs} for t in tabs: names=' | '.join('%s%s%s'%('▶'if it['on']else'',it['t'][:14],'(새창)'if it['blank']else'') for it in t['items']) print('r%d B%s %-16s [%s n%d] %s'%(r,bn,lab[:16],t['cls'][:18],t['n'],names),flush=True) except Exception as e: print('r%d ERR %s'%(r,str(e)[:30]),flush=True) b.close() json.dump(res,open('_cy3_tabs.json','w',encoding='utf-8'),ensure_ascii=False,indent=1) print('\n탭보유 행수:',len(res))