파이썬 교재 · 22편 / 27편

파이썬 자동화 스크립트

잠든 새벽에도 돌아가는 코드. 1~21편이 한 파일로 모인다.

실전읽는 시간 7분2026-05-13
일일 리포트를 cron 으로 9시에 실행하는 코드와 cron 설정 화면

21편까지의 도구들은 다 한 가지 목표를 향했습니다 — 잡일을 컴퓨터에게 떠넘기기. 매일 같은 폴더의 파일을 정리, 환율 받아 엑셀에 추가, 로그 보고서 만들어 메일, 신규 가입자 슬랙 알림. 이런 작업이 한 번 짠 스크립트 + cron 한 줄로 사람 손을 떠납니다. 22편은 1~21편 도구를 한 파일에 묶는 실전.

22편을 마치면 ① 잘 쓴 스크립트 5요소 ② argparse 로 CLI 인자 ③ logging 으로 로그 ④ cron·systemd timer 로 스케줄 ⑤ 알림(메일·슬랙) 기본 — 5가지로 완성된 자동화를 만듭니다.

잘 쓴 자동화 스크립트의 5요소

#!/usr/bin/env python3
"""일일 매출 리포트 — sales.csv → summary.csv (어제 데이터 기준)."""
import argparse, logging, sys
from datetime import date, timedelta
from pathlib import Path
import pandas as pd

def main() -> int:
    ap = argparse.ArgumentParser()
    ap.add_argument("--input", default="sales.csv")
    ap.add_argument("--out", default=None)
    args = ap.parse_args()

    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s [%(levelname)s] %(message)s",
    )
    log = logging.getLogger(__name__)

    yesterday = date.today() - timedelta(days=1)
    out = Path(args.out or f"summary-{yesterday}.csv")

    try:
        df = pd.read_csv(args.input)
        df = df[df["date"] == str(yesterday)]
        summary = df.groupby("item")["price"].agg(["sum", "count"])
        summary.to_csv(out)
        log.info("저장: %s (%d items)", out, len(summary))
        return 0
    except FileNotFoundError as e:
        log.error("입력 파일 없음: %s", e)
        return 1
    except Exception as e:
        log.exception("예기치 못한 오류")
        return 2

if __name__ == "__main__":
    sys.exit(main())

5요소가 다 들어갔습니다.

  1. shebang #!/usr/bin/env python3 — 직접 실행 가능 (chmod +x./script.py)
  2. docstring — 이 스크립트가 뭐 하는지 한 줄
  3. argparse--input·--out 같은 옵션 + --help 자동 생성
  4. logging — print 대신 시각·레벨 포함, 나중에 파일 출력 변경 가능
  5. main() + sys.exit — 성공 0, 실패 1·2 종료 코드. cron 이 이걸 보고 실패 알림

argparse — CLI 인자 처리

import argparse

ap = argparse.ArgumentParser(description="매출 리포트 생성")
ap.add_argument("--date", type=str, help="YYYY-MM-DD")
ap.add_argument("--top", type=int, default=10, help="상위 N개")
ap.add_argument("--verbose", "-v", action="store_true")
ap.add_argument("file", nargs="?", default="sales.csv")  # 위치 인자

args = ap.parse_args()
# python report.py sales.csv --date 2026-05-13 --top 5 -v
# args.date == "2026-05-13", args.top == 5, args.verbose == True

옵션 추가 한 줄에 --help 메시지도 자동 생성됩니다. 입력 도구가 사람이 쓸 수 있는 진짜 CLI 가 돼요.

logging — print 보다 항상 좋다

import logging

logging.basicConfig(
    filename="report.log",                # 파일에 누적
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
log = logging.getLogger(__name__)

log.debug("디버그 정보")     # 안 보임 (level > DEBUG)
log.info("정상 메시지")
log.warning("주의")
log.error("에러 발생")
log.exception("예외 + traceback 같이")

📌 print 와 logging 의 차이

print 는 "지금 화면에 찍기", logging 은 "수준·시각·위치를 붙여 어딘가에 기록". 자동화는 사람이 안 보는 새벽에 돌아서, 나중에 무슨 일이 있었는지 추적이 필수. logging 한 줄로 오늘 새벽 3시에 무엇이 실패했는지 알 수 있어요.

cron — 시간 맞춰 실행

# 셸에서
$ crontab -e

# 편집기에 한 줄 추가 — 매일 오전 9시
0 9 * * * /home/user/myapp/.venv/bin/python /home/user/myapp/daily_report.py >> /home/user/myapp/cron.log 2>&1

# 5분마다
*/5 * * * * /path/to/python /path/to/script.py

# 매주 월요일 8시
0 8 * * 1 /path/to/python /path/to/weekly.py

크론 다섯 칸: 분 시 일 월 요일. * 는 "모두". crontab.guru 가 자연어로 풀어 보여줘서 입문자에게 안전합니다.

⚠️ cron 함정 3가지.절대 경로 사용 — cron 환경엔 PATH 가 거의 비어있음. python 이 아니라 /home/u/.venv/bin/python. ② 표준 출력은 사라진다>> logfile 2>&1 로 리다이렉트. ③ 가상환경 활성화 안 됨 — venv 의 python 을 직접 호출하면 자동 활성화 효과.

systemd timer — cron 의 현대식 대체

# /etc/systemd/system/daily-report.service
[Unit]
Description=Daily sales report

[Service]
Type=oneshot
ExecStart=/home/user/myapp/.venv/bin/python /home/user/myapp/daily_report.py
User=user
WorkingDirectory=/home/user/myapp

# /etc/systemd/system/daily-report.timer
[Unit]
Description=Run daily report at 09:00

[Timer]
OnCalendar=*-*-* 09:00:00
Persistent=true

[Install]
WantedBy=timers.target

$ sudo systemctl enable --now daily-report.timer

cron 보다 로그·실패 알림이 깔끔합니다. ubuntu-linux 19~20편(systemd·cron)을 그대로 응용.

알림 — 메일·슬랙 + 마무리

# 슬랙 Incoming Webhook — 환경 변수에 저장
import os, requests

def slack(text: str):
    url = os.environ["SLACK_WEBHOOK_URL"]
    requests.post(url, json={"text": text}, timeout=10)

# 메일 (smtplib) — 회사 메일은 보통 SMTP 정보가 회사에서 줌
import smtplib
from email.message import EmailMessage

def send_mail(to: str, subject: str, body: str):
    msg = EmailMessage()
    msg["Subject"] = subject
    msg["From"] = "[email protected]"
    msg["To"] = to
    msg.set_content(body)
    with smtplib.SMTP("smtp.junai.ai", 587) as s:
        s.starttls()
        s.login(os.environ["SMTP_USER"], os.environ["SMTP_PASS"])
        s.send_message(msg)

자동화 + 알림 = 자동으로 일이 끝나고 사람에게는 결과만. 회사에서 본인이 매일 5분씩 하던 일을 한 번 스크립트로 만들면 1년에 약 20시간이 돌아옵니다.

다음 미션: ① 다운로드 폴더의 .png 를 날짜별 하위 폴더로 정리하는 스크립트 ② 환율 API 호출해 CSV 에 누적 ③ 본인이 매일 반복하는 작업 하나를 골라 스크립트화.

다음 편 미리보기

23편 — "파이썬 웹 크롤링": requests + BeautifulSoup·Playwright 입문. 정적 페이지부터 JS 동적 페이지까지.

📚 27편 파이썬 교재 시리즈 — 22/27편
← 21편 "pandas 기초" · 다음: 23편 "웹 크롤링"

© 2026 주나이테크(주) @JUNAITECH