import openpyxl import requests from bs4 import BeautifulSoup import re import time def crawl_moe_license_separate_save(origin_path, save_path, sheet_name=None): """ 교육부 엑셀 리스트 맞춤형 크롤러 (원본 읽기 -> 크롤링 -> 별도 파일로 저장) """ try: # 1. 원본 엑셀 파일 로드 wb = openpyxl.load_workbook(origin_path) ws = wb[sheet_name] if sheet_name else wb.active print(f"📂 원본 파일을 성공적으로 불러왔습니다: {origin_path}") except Exception as e: print(f"❌ 원본 엑셀 파일을 열 수 없습니다. 경로를 확인해주세요. 에러: {e}") return # 웹 서버 차단 방지용 User-Agent 설정 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36' } print("🚀 교육부 공공누리 라이선스 크롤링을 시작합니다. (대상: 3행 ~ 마지막 행)") # 3행부터 데이터가 있는 마지막 행까지 순회 for row in range(3, ws.max_row + 1): url_cell = ws.cell(row=row, column=11).value # K열 (11번째 열) if not url_cell: continue url = str(url_cell).strip() # [예외 처리] URL에 특정 도메인(www.moe.go.kr)이 포함되어 있지 않은 경우 처리 if 'www.moe.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열: 빈칸 print(f"[{row}행] 외부 도메인 필터링 -> '사이트' 분류 처리") 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') # --- 1단계. L열 / M열: 게시판 형태 및 수량 판별 --- board_top_div = soup.find('div', {'data-board': 'top'}) is_board = False total_count = None if board_top_div: strong_tag = board_top_div.find('strong') if strong_tag: span_tag = strong_tag.find('span') if span_tag: # 숫자 데이터만 추출 count_text = re.sub(r'[^0-9]', '', span_tag.text) if count_text: total_count = int(count_text) is_board = True # 형태 판별 결과 저장 (대시 대신 무조건 빈칸 규칙 적용) if is_board: ws.cell(row=row, column=12, value="게시판") # L열 ws.cell(row=row, column=13, value=total_count) # M열 else: ws.cell(row=row, column=12, value="페이지") # L열 ws.cell(row=row, column=13, value="") # M열 (빈칸) # --- 2단계. O, P, Q열: