2026년 9월 6일 일요일

[행정/연구] 교육청 공지·일정 스크래핑 대시보드 - 매일 아침 무인 수집



교육청 공지가 아침마다 교무실 대시보드로 — 웹 명세서 기반 스크래핑 완전 정복

📋 교육청 공지사항과 직속기관 연수 일정 웹사이트를 웹 명세서(specification) 기반 파이썬 스크립트가 매일 아침 자동 수집해, 단일 HTML 대시보드로 만들어 교무실 PC에서 공유합니다. Windows 작업 스케줄러(Task Scheduler)에 등록하면 무인 실행 — 연수·마감 일정을 더는 놓치지 않습니다.

대시보드는 매일 아침 코드가 새로 만들어 줍니다 — 지난 연재에서 정리한 심기 모드(데이터 임베딩)의 자동화 버전입니다. 데이터는 공개 정보를 '받아오기만' 합니다 — 외부 전송 0, 학생 개인정보 0.

📖 한 줄 정의

심기 모드(데이터 임베딩): API 데이터를 미리 받아 HTML 파일 안 상수로 박아두는 방식(앱 실행 중 외부 통신 0).

학내망 원칙: 학교 배포 웹앱은 개인정보 수집·저장·전송 없음(외부 CDN·API 호출 0, 단일 파일) — 학생은 학내망에서 교사 PC 서버에 접속.

1. 3대 핵심 분석 비교표

무엇이 바뀌었나요? / 영역 초보자를 위한 쉬운 설명 이렇게 한번 써보세요!
해결 문제 연수·마감 일정이 사이트마다 흩어져 놓치는 문제 → 매일 아침 자동 수집·한 화면 정리. 아침 대시보드에서 오늘 일정 확인.
웹 명세서 우선 명세서 방법 그대로 — 페이지·칸·셀렉터(selector)·주기를 지도로 남깁니다. 사이트 구조가 바뀌면 명세서만 고칩니다. 교육청 공지 페이지 명세서 2행 작성.
대시보드 생성 파이썬이 수집 결과를 단일 HTML 파일로 자동 생성 — 심기 모드의 자동 갱신 버전. 외부 라이브러리 없이 열립니다. 교무실대시보드.html 더블클릭.
무인 실행 Windows 작업 스케줄러(Task Scheduler)에 매일 07:30 등록 — 맥·리눅스는 크론(cron)으로 같은 원리. schtasks 등록 명령 한 줄.
원칙·안전 공개 정보 수신만 — 외부 전송 0, 학생 개인정보 0, 교무실 PC(학내망) 실행. 수집 결과는 학교 내부 공유용. 대시보드 하단에 '출처·수집 시각' 표기.

2. 핵심 아키텍처 해설 — 수집하고, 만들고, 등록한다

① 수집: 명세서에서 온 셀렉터

import requests
from bs4 import BeautifulSoup

SELECTORS = {
    "공지": ".board-list li",        # 명세서에서 온 값(예시 — 수업 시점에 확인)
    "제목": "b.tit",
    "날짜": "span.date"
}

res = requests.get(URL, timeout=10)
soup = BeautifulSoup(res.text, "html.parser")
notices = []
for li in soup.select(SELECTORS["공지"]):
    notices.append({
        "title": li.select_one(SELECTORS["제목"]).get_text(strip=True),
        "date": li.select_one(SELECTORS["날짜"]).get_text(strip=True)
    })

URL·셀렉터 모두 명세서에서 옵니다 — 코드에는 '명세서 몇 행' 주석이 함께 갑니다.

② 대시보드 생성: 파이썬이 HTML을 심는다

html = '<html><head><meta charset="utf-8">'
html = html + '<style>body{font-family:"맑은 고딕";max-width:720px;margin:40px auto;}</style>'
html = html + '</head><body><h1>오늘의 교육청 공지·일정</h1>'

for item in notices:
    html = html + '<p>' + item["date"] + ' · ' + item["title"] + '</p>'

html = html + '</body></html>'
open("교무실대시보드.html", "w", encoding="utf-8").write(html)

이 파일이 곧 '어제의 심기 모드가 자동으로 갱신되는 버전'입니다 — 매일 아침, 코드가 데이터를 파일 안에 심어줍니다.

③ 무인 실행: 작업 스케줄러 등록

schtasks /create /tn "교육청공지수집" /tr "python 수집기.py" /sc daily /st 07:30
  • /sc daily /st 07:30 — 매일 아침 7시 30분 자동 실행.
  • 맥·리눅스라면 크론(cron)으로 30 7 * * * 한 줄 — 원리는 같습니다.
  • 실행 결과(성공·건수)는 로그 파일로 남겨 '조용한 실패'를 막습니다.

④ 운영 원칙

  • 출처 표기: 대시보드 하단에 '수집 시각·원문 링크'를 항상 남깁니다.
  • 공개 정보만: 학생 개인정보는 수집 대상이 아니며, 외부 전송도 없습니다(학내망 원칙 정합).
  • 명세서 갱신 루틴: 사이트 개편이 감지되면(빈 목록·'확인 필요') 명세서를 고치고 셀렉터를 교체합니다.

3. 초보자를 위한 바이브 코딩 실전 사용 예시

  1. 프롬프트 복사 — 아래 '제미나이 전용 에러 제로 프롬프트' 전체를 Gemini에 붙여넣습니다.
  2. 역질문 답변 — 수집 대상 페이지, 실행 시각, 대시보드 서식에 답합니다.
  3. 스케줄러 등록 — 스크립트 실행 확인 후 schtasks 명령 한 줄로 무인화.

제미나이 전용 에러 제로 프롬프트 (파이썬판)

[🚨 에러 방지 기본 안전장치]
1. 라이브러리는 requests, beautifulsoup4만 사용한다.
2. 웹 명세서(페이지·칸·셀렉터·주기)를 먼저 마크다운 표로 만들어 달라고 요청한 뒤, 셀렉터를 상수로 옮긴다.
3. 수집 결과가 0건이면 대시보드에 '오늘 수집 결과 없음 — 명세서 확인 필요'를 남긴다(조용한 실패 금지).
4. 대시보드는 외부 CSS·JS 없는 단일 HTML로 만들고, 하단에 수집 시각·출처를 표기한다.
5. 로그 파일에 실행 시각·건수·오류를 기록한다.
6. 이 스크립트는 공개 정보를 받아오기만 한다 — 데이터를 외부로 전송하는 기능을 만들지 않는다(학내망 원칙).
7. // TODO, pass 등 미완성 코드 금지 — 끝까지 완성한다.

[❓ 역질문 유도]
코드를 바로 만들지 말고, 아래 3가지를 먼저 나에게 질문한 뒤 내 답변으로 설계를 확정한다.
Q1. 어느 사이트의 무엇을 수집할까? (교육청 공지 / 직속기관 연수 일정 등 — URL을 함께 알려준다)
Q2. 실행 시각은? (매일 07:30 기본)
Q3. 대시보드 서식은? (최신순 목록 + 날짜·제목 기본)

🎯 에디터 한줄평

'놓치는 일정'이 '아침마다 도착하는 대시보드'로 — 행정 안전망이 코드로 완성됩니다. 명세서와 셀렉터 상수를 분리한 설계가 유지보수의 핵심이고, '수집 결과 0건'을 조용히 넘기지 않는 습관이 자동화의 신뢰를 만듭니다. 심기 모드가 '자동으로 갱신되는 심기'로 진화하는 순간이기도 합니다.

📚 기술·교육 참고 링크