import os import requests from bs4 import BeautifulSoup import openpyxl def analyze_page_copyright_final(): input_file = r"C:\Users\hehih\ownCloud\알바\인천광역시\인천광역시_홈페이지_사이트_20260520_완료_저작물유형.xlsx" output_file = r"C:\Users\hehih\ownCloud\알바\인천광역시\인천광역시_홈페이지_사이트_20260520_완료_저작물유형_r2_temp.xlsx" if not os.path.exists(input_file): print(f"오류: '{input_file}' 파일이 존재하지 않습니다. 경로를 확인해주세요.") return # 1. 엑셀 파일 로드 (기존 정렬, 배경색, 눈금선 등 스타일 서식 철저 보존) wb = openpyxl.load_workbook(input_file, data_only=False) sheet = wb.active headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } # 제외할 이미지 경로 패턴 선언 (공공누리 마크 등 기본 레이아웃 이미지) exclude_img_pattern = "/humanframe/globaltheme/assets/image/layout/img_opentype" print("=" * 80) print(" [페이지 마스터 엔진] L열 '페이지' 필터링 및 공공누리 이미지 제외 처리 가동") print("=" * 80) # 2. 데이터 영역 순회 (4행부터 끝까지) for row_idx in range(4, sheet.max_row + 1): board_type = sheet.cell(row=row_idx, column=12).value # L열 (게시판형태) page_url = sheet.cell(row=row_idx, column=11).value # K열 (주소url) # 🎯 규칙 준수: L열의 값이 정확히 '페이지'인 행만 작업 대상으로 지정 if board_type != "페이지" or not page_url: continue page_url = page_url.strip() print(f"\n[행 {row_idx}] 페이지 접속 ➡️ {page_url}") try: # '페이지' 형태는 목록을 거치지 않고 K열 주소의 본문을 다이렉트로 파싱 response = requests.get(page_url, headers=headers, timeout=10) if response.status_code != 200: print(f" └─ [경고] 페이지 접근 실패 (Status: {response.status_code})") continue soup = BeautifulSoup(response.text, "html.parser") # 본문 영역 지정:
main_content = soup.find("main", class_="content") if not main_content: print(" └─ [경고] 본문 영역(
)을 찾을 수 없습니다.") sheet.cell(row=row_idx, column=14).value = "" continue html_str = str(main_content).lower() text_str = main_content.get_text().strip() has_text = False has_image = False has_excluded_media = False # 예외 자원(영상, 오디오 등) 감지 플래그 # 3. 본문 자원 상태 분석 if text_str: has_text = True # --- 이미지 감지 및 특정 이미지 예외 필터링 로직 --- img_tags = main_content.find_all("img") valid_image_found = False for img in img_tags: src = img.get("src", "") # 지정해주신 공공누리 마크 이미지 경로가 src에 포함되어 있으면 제외하고 패스 if exclude_img_pattern in src: continue # 예외 패턴이 없는 유효한 이미지가 발견되었을 때 로그 출력 및 플래그 활성화 valid_image_found = True parent_tag = img.parent print(f" └─ 📸 [유효 이미지 발견] 감싸고 있는 태그 구조:\n{parent_tag.prettify()}") # inline style 배경이미지 체크 (제외 패턴이 포함되지 않은 경우만) if valid_image_found or ("background-image:" in html_str and exclude_img_pattern not in html_str): has_image = True # 표준 감사 지침 예외 대상 필터링 조건 (영상, 오디오, 글꼴, 3D) excluded_extensions = [ ".mp4", ".avi", ".mkv", ".wmv", ".mov", ".flv", ".mp3", ".wav", ".ogg", ".wma", ".m4a", ".ttf", ".woff", ".woff2", ".otf", ".eot", ".obj", ".gltf", ".glb", ".fbx", ".3ds" ] excluded_tags = ["video", "iframe", "embed", "object", "audio", "canvas"] if (main_content.find(excluded_tags) or any(ext in html_str for ext in excluded_extensions) or "youtube.com/embed" in html_str or "youtu.be" in html_str or "@font-face" in html_str): has_excluded_media = True # 4. 저작물 유형 최종 판별 로직 적용 result_type = "" if has_excluded_media or (not has_text and not has_image): result_type = "" # 예외 자원이 있거나 내용이 없으면 공백 유지 elif has_text and has_image: result_type = "어문, 이미지" elif has_text: result_type = "어문" elif has_image: result_type = "이미지" # 5. 기존 엑셀 서식을 철저히 유지하며 N열(14번째 열)에 데이터 입력 if result_type: sheet.cell(row=row_idx, column=14).value = result_type print(f" └─ 🎯 판별 완료 [N열 기입]: {result_type}") else: sheet.cell(row=row_idx, column=14).value = "" print(" └─ 🎯 판별 완료 [N열 기입]: 공백 유지 (내용 없음, 예외 미디어 혹은 레이아웃 이미지 감지)") except Exception as e: print(f" └─ ❌ [행 처리 실패] 에러 건너뜀: {e}") continue # 6. 최종 파일 안전 저장 print("\n" + "=" * 80) print(" L열 '페이지' 필터링 및 공공누리 필터링이 적용된 분석 공정이 완료되었습니다.") wb.save(output_file) print(f"💾 결과 파일 생성 완료: {output_file}") print("=" * 80) if __name__ == "__main__": analyze_page_copyright_final()