import os import re import time import requests from bs4 import BeautifulSoup import openpyxl from openpyxl.utils import get_column_letter def analyze_mohw_site(excel_path): # 1. 엑셀 파일 로드 if not os.path.exists(excel_path): print(f"파일을 찾을 수 없습니다: {excel_path}") return wb = openpyxl.load_workbook(excel_path) ws = wb.active # 현재 활성화된 시트 선택 # 기본 도메인 정의 base_url = "https://www.mohw.go.kr" # 웹 요청 시 사용할 User-Agent 설정 (차단 방지) 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" } print("크롤링 및 분석을 시작합니다...") # 2. 3행부터 마지막 행까지 루프 수행 max_row = ws.max_row for row in range(3, max_row + 1): url = ws.cell(row=row, column=11).value # K열 (11번째) # URL이 비어있으면 건너뜀 if not url: continue url = url.strip() print(f"[{row}/{max_row} 행 분석 중] URL: {url}") # 예외 처리: K열에 www.mohw.go.kr이 포함되어 있지 않은 경우 if "www.mohw.go.kr" not in url: ws.cell(row=row, column=12, value="사이트") # L열 ws.cell(row=row, column=13, value="") # M열 (빈칸) ws.cell(row=row, column=15, value="미부착") # O열 ws.cell(row=row, column=16, value="") # P열 ws.cell(row=row, column=17, value="") # Q열 continue try: # 웹페이지 요청 (타임아웃 10초 설정) response = requests.get(url, headers=headers, timeout=10) response.raise_for_status() # 한글 깨짐 방지 response.encoding = response.apparent_encoding soup = BeautifulSoup(response.text, 'html.parser') time.sleep(1.0) # 디레이 시간 부여 (1초) # 게시판 형태 및 수량 판별 로직 (L열, M열) board_type = "페이지" total_count = "" # 패턴 A 탐색: total_count_tag_a = soup.find(id="totalCount") # 패턴 B 탐색: total_count_tag_b = soup.select_one("span.total b") if total_count_tag_a: count_text = total_count_tag_a.get_text(strip=True) # 숫자만 추출 numbers = re.findall(r'\d+', count_text) if numbers: total_count = int(numbers[0]) board_type = "게시판" elif total_count_tag_b: count_text = total_count_tag_b.get_text(strip=True) numbers = re.findall(r'\d+', count_text) if numbers: total_count = int(numbers[0]) board_type = "게시판" # 판별 결과 기록 (L열, M열) ws.cell(row=row, column=12, value=board_type) ws.cell(row=row, column=13, value=total_count) # 페이지일 경우 total_count가 ""이므로 빈칸 처리됨 # 초기 결과 변수 설정 license_type = "미부착" mark_location = "" has_mark = "" # 공공누리 마크 식별을 위한 변수 (현재 정보가 없으므로 미부착 처리용 플래그) found_license = False if board_type == "게시판": # --- [게시판 로직] --- # 1차 탐색 영역 (목록화면 전체 body 혹은 특정 영역 내에서 라이선스 탐색 가능) # 여기서는 목록 화면 전체에서 우선 매칭되는지 체크 가능 (필요시 영역 축소 가능) # 상세 페이지 URL 추출 (최대 5개 크롤링) detail_links = [] list_table = soup.find("table", class_="tstyle_list") if list_table: a_tags = list_table.select("td.txt_left a") for a in a_tags[:5]: # 상위 5개만 추출 href = a.get("href", "") if href: # 상대 경로일 경우 절대 경로로 결합 if href.startswith("/"): detail_links.append(base_url + href) elif href.startswith("http"): detail_links.append(href) else: detail_links.append(base_url + "/" + href) # 2차 탐색 영역 (상세 글 5개 순회) for detail_url in detail_links: try: detail_res = requests.get(detail_url, headers=headers, timeout=10) detail_res.raise_for_status() detail_res.encoding = detail_res.apparent_encoding detail_soup = BeautifulSoup(detail_res.text, 'html.parser') time.sleep(0.8) # 상세 페이지 요청 간 디레이 # 상세페이지 본문 영역 선택:
article_body = detail_soup.find("article", class_="board_view") if article_body: # 💡 [추후 수정 공간] 공공누리 마크 식별 패턴이 정의되면 이곳에 코드를 삽입합니다. # 예: if "kogl" in str(article_body): ... pass except Exception as e: print(f"상세 페이지 접근 오류 ({detail_url}): {e}") continue else: # --- [페이지 로직] --- # 본문 영역 선택:
contents_body = soup.find(id="contents_body") if contents_body: # 💡 [추후 수정 공간] 공공누리 마크 식별 패턴이 정의되면 이곳에 코드를 삽입합니다. pass # 최종 결과 기록 (O, P, Q열) ws.cell(row=row, column=15, value=license_type) ws.cell(row=row, column=16, value=mark_location) ws.cell(row=row, column=17, value=has_mark) except Exception as e: print(f"{row}행 처리 중 오류 발생: {e}") # 오류 발생 시 기본값 혹은 빈칸 처리 ws.cell(row=row, column=12, value="에러") ws.cell(row=row, column=13, value="") ws.cell(row=row, column=15, value="확인불가") ws.cell(row=row, column=16, value="") ws.cell(row=row, column=17, value="") # 3. 엑셀 파일 저장 output_path = excel_path.replace(".xlsx", "_결과.xlsx") wb.save(output_path) print(f"모든 분석이 완료되었습니다. 결과가 저장되었습니다: {output_path}") # 코드 실행부 (파일명이 'target_list.xlsx'인 경우 예시) if __name__ == "__main__": # 처리하고자 하는 엑셀 파일 경로를 입력하세요. excel_file_path = r"D:\01.프로젝트\DB수집\2주차\보건복지부\보건복지부_활성화.xlsx" analyze_mohw_site(excel_file_path)