import os import time import requests from bs4 import BeautifulSoup from requests.adapters import HTTPAdapter from urllib3.util import Retry from openpyxl import load_workbook def fill_board_counts_only(file_path, output_path): # 1. 원본 서식을 그대로 유지하기 위해 openpyxl로 로드 wb = load_workbook(file_path) ws = wb.active # openpyxl 열 번호 지정 (1부터 시작) K_col = 11 # K열 (URL) L_col = 12 # L열 (게시판구분) M_col = 13 # M열 (수량/건수) # 강력한 웹 크롤링 세션 구성 session = requests.Session() retry_strategy = Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504]) adapter = HTTPAdapter(max_retries=retry_strategy) session.mount("http://", adapter) session.mount("https://", adapter) session.headers.update({ "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", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7", }) total_rows = ws.max_row print(f"총 {total_rows}행이 확인되었습니다. 87행부터 L/M열 수집을 시작합니다...\n") # 87행부터 마지막 행까지 순차적으로 탐색 for current_row in range(87, total_rows + 1): target_url = str(ws.cell(row=current_row, column=K_col).value).strip() # URL 주소가 비어있거나 올바르지 않으면 패스 if not target_url.startswith("http") or target_url == "None": print(f"[{current_row} / {total_rows}행] -> URL이 없거나 올바르지 않습니다. (건너뜀)") continue print(f"[{current_row} / {total_rows}행] 처리 중... -> URL: {target_url}") # 1. K열 URL이 /list.do로 끝나는지 검사 # 쿼리 스트링(?...)이 붙어 있을 수 있으므로 분리 후 매칭 url_path = target_url.split('?')[0] if url_path.endswith("/list.do"): # L열에 '게시판' 작성 ws.cell(row=current_row, column=L_col).value = "게시판" # 방화벽 우회를 위한 안전 딜레이 time.sleep(0.5) try: session.headers.update({"Referer": target_url}) response = session.get(target_url, timeout=15) if response.status_code == 200: soup = BeautifulSoup(response.text, "html.parser") # 2.
전체 숫자
탐색 total_div = soup.find("div", class_="total") if total_div and total_div.find("span"): count_text = total_div.find("span").get_text(strip=True) # 숫자가 정상적이라면 M열에 정수형 숫자로 입력 if count_text.isdigit(): ws.cell(row=current_row, column=M_col).value = int(count_text) print(f" -> [성공] '게시판' 마킹 및 건수 기입 완료: {count_text}건") else: ws.cell(row=current_row, column=M_col).value = count_text print(f" -> [주의] 텍스트 건수 기입: {count_text}") else: print(" -> [알림] 게시판 형태이나 total 건수 태그를 찾지 못했습니다.") else: print(f" -> [실패] HTTP 응답 에러 코드: {response.status_code}") except Exception as e: print(f" -> [오류] 웹페이지 접속 및 파싱 실패: {e}") else: # /list.do로 끝나지 않는 일반 페이지 처리 ws.cell(row=current_row, column=L_col).value = "페이지" print(" -> 일반 '페이지'입니다. (건수 수집 패스)") # 스타일 유지 상태로 안전하게 저장 wb.save(output_path) print(f"\n✨ 수집이 전부 완료되었습니다! 파일 저장 완료:\n{output_path}") # --- 실행 영역 --- input_excel = r"C:\Users\hehih\ownCloud\알바\2주차\외교부\외교부_업데이트_활성화_r4.xlsx" output_excel = r"C:\Users\hehih\ownCloud\알바\2주차\외교부\외교부_업데이트_활성화_r5.xlsx" fill_board_counts_only(input_excel, output_excel)