공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
66 lines
3.0 KiB
Python
66 lines
3.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""N에 '영상' 있는 행을 렌더해 본문 영역 실제 동영상(youtube/vimeo iframe·video태그) 확인.
|
|
없으면 영상 제거(푸터 유튜브 오탐 정리). 변경 셀 하늘색. 사용: python _video_verify.py [num ...]"""
|
|
import sys, io, os, glob, warnings
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
|
warnings.filterwarnings('ignore')
|
|
import openpyxl
|
|
from openpyxl.styles import PatternFill
|
|
from playwright.sync_api import sync_playwright
|
|
|
|
BASE = r"D:\01.프로젝트\DB수집\작업파일\공공기관2"
|
|
BLUE = PatternFill("solid", fgColor="FFBDD7EE", bgColor="FFBDD7EE")
|
|
|
|
CHECK_JS = """
|
|
() => {
|
|
// 본문 후보(푸터/헤더/내비 제외)에서 동영상 탐지
|
|
const bad = ['footer','header','gnb','lnb','nav','foot','top_','quick','sns','family'];
|
|
function inChrome(el){ let p=el; while(p){ const c=((p.className||'')+' '+(p.id||'')).toLowerCase(); if(bad.some(b=>c.includes(b))) return true; p=p.parentElement; } return false; }
|
|
let v=false;
|
|
document.querySelectorAll('iframe').forEach(f=>{ if(/youtube|youtu\\.be|vimeo|player|video/i.test(f.src||'') && !inChrome(f)) v=true; });
|
|
document.querySelectorAll('video').forEach(el=>{ if(!inChrome(el)) v=true; });
|
|
return v;
|
|
}
|
|
"""
|
|
|
|
def run(nums):
|
|
with sync_playwright() as p:
|
|
br = p.chromium.launch(headless=True)
|
|
ctx = br.new_context(ignore_https_errors=True, viewport={'width':1600,'height':1000})
|
|
pg = ctx.new_page()
|
|
for num in nums:
|
|
fs = [x for x in glob.glob(os.path.join(BASE, f"{num}.*", "*.xlsx")) if "_backup" not in x and "~$" not in x]
|
|
if not fs:
|
|
continue
|
|
fp = fs[0]
|
|
wb = openpyxl.load_workbook(fp)
|
|
ws = wb.active
|
|
changed = 0
|
|
rows = [r for r in range(3, ws.max_row+1)
|
|
if ws.cell(r,2).value is not None and ws.cell(r,14).value and '영상' in str(ws.cell(r,14).value)]
|
|
for r in rows:
|
|
url = ws.cell(r, 11).value
|
|
n = str(ws.cell(r, 14).value)
|
|
if not url or not url.startswith('http'):
|
|
continue
|
|
has = False
|
|
try:
|
|
pg.goto(url, wait_until='domcontentloaded', timeout=20000)
|
|
pg.wait_for_timeout(1500)
|
|
has = pg.evaluate(CHECK_JS)
|
|
except Exception:
|
|
has = True # 못 열면 보존
|
|
if not has:
|
|
parts = [x for x in n.split(',') if x != '영상']
|
|
newn = ','.join(parts) if parts else '어문'
|
|
ws.cell(r, 14).value = newn
|
|
ws.cell(r, 14).fill = BLUE
|
|
changed += 1
|
|
wb.save(fp)
|
|
print(f"[{os.path.basename(os.path.dirname(fp))}] 영상행 {len(rows)} → 오탐제거 {changed}")
|
|
br.close()
|
|
|
|
if __name__ == '__main__':
|
|
nums = [int(x) for x in sys.argv[1:]] or [1,2,5,6,7,8,9,10,11,12,13,14,15,16]
|
|
run(nums)
|