파이썬 자동화 스크립트
잠든 새벽에도 돌아가는 코드. 1~21편이 한 파일로 모인다.
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요소가 다 들어갔습니다.
- shebang
#!/usr/bin/env python3— 직접 실행 가능 (chmod +x후./script.py) - docstring — 이 스크립트가 뭐 하는지 한 줄
- argparse —
--input·--out같은 옵션 +--help자동 생성 - logging — print 대신 시각·레벨 포함, 나중에 파일 출력 변경 가능
- 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 가 자연어로 풀어 보여줘서 입문자에게 안전합니다.
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 동적 페이지까지.
← 21편 "pandas 기초" · 다음: 23편 "웹 크롤링"