10편. 실전 자동화 6: 공공데이터 API + 텔레그램으로 관심 종목 종가 매일 받기
- 공유 링크 만들기
- X
- 이메일
- 기타 앱
8편에서 텔레그램 봇으로 메시지를 보내는 법을, 9편에서 공공데이터포털 오픈 API로 주식 시세를 받는 법을 배웠습니다. 이번 10편에서는 두 가지를 하나로 합쳐서 관심 종목의 전날 종가와 등락률을 매일 텔레그램으로 받아 보는 봇을 완성합니다. 코드 한 파일이면 됩니다.
1. 완성하면 이런 메시지가 옵니다
📈 관심 종목 종가 (10/29 기준)
삼성전자 71,200원 (+1.42%)
SK하이닉스 185,000원 (-0.54%)
NAVER 198,500원 (+0.25%)
위 숫자는 화면 모양을 보여 주기 위한 예시입니다. 실제로는 API에서 받은 값이 그대로 들어갑니다.
2. 준비물 3가지
| 준비물 | 어디서 | 참고 글 |
|---|---|---|
| 공공데이터포털 인증키(Decoding) | 금융위원회_주식시세정보 활용신청 | 9편 |
| 텔레그램 봇 토큰 | 텔레그램 BotFather | 8편 |
| 내 채팅방 chat_id | 봇에게 메시지를 보낸 뒤 getUpdates 주소로 확인 | - |
3. 언제 실행해야 할까? (중요)
9편에서 설명했듯 이 API는 실시간이 아니라 기준일 다음 영업일 오후 1시 이후에 데이터가 갱신됩니다. 그래서 아침 8시에 돌리면 어제 종가가 아니라 그 전 영업일 종가가 옵니다. 매일 저녁(예: 오후 6시)에 실행하면 전날 종가를 안정적으로 받을 수 있습니다. 코드는 날짜를 직접 정하지 않고 “최근 10일 데이터 중 가장 최신 날짜”를 고르도록 만들어서, 주말이나 공휴일에도 오류 없이 돌아갑니다.
4. 전체 코드
import requests
from datetime import datetime, timedelta
SERVICE_KEY = "공공데이터포털_Decoding_인증키"
BOT_TOKEN = "텔레그램_봇_토큰"
CHAT_ID = "내_chat_id"
API_URL = "https://apis.data.go.kr/1160100/GetStockSecuritiesInfoService_V2/getStockPriceInfo_V2"
STOCKS = ["삼성전자", "SK하이닉스", "NAVER"] # 관심 종목 이름 (정확한 종목명)
def get_latest_price(name):
"""최근 10일 안에서 가장 최신 날짜의 시세 1건을 돌려준다."""
begin = (datetime.now() - timedelta(days=10)).strftime("%Y%m%d")
params = {
"serviceKey": SERVICE_KEY,
"resultType": "json",
"numOfRows": 20,
"pageNo": 1,
"itmsNm": name,
"beginBasDt": begin,
}
res = requests.get(API_URL, params=params, timeout=10)
items = res.json()["response"]["body"]["items"]["item"]
if isinstance(items, dict):
items = [items]
return max(items, key=lambda x: x["basDt"]) # 가장 최근 날짜
def send_telegram(text):
url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
requests.post(url, data={"chat_id": CHAT_ID, "text": text}, timeout=10)
lines = []
base_date = ""
for name in STOCKS:
try:
it = get_latest_price(name)
base_date = f"{it['basDt'][4:6]}/{it['basDt'][6:]}"
price = int(it["clpr"])
rate = float(it["fltRt"])
lines.append(f"{it['itmsNm']} {price:,}원 ({rate:+.2f}%)")
except Exception as e:
lines.append(f"{name} 조회 실패 ({e})")
message = f"📈 관심 종목 종가 ({base_date} 기준)\n" + "\n".join(lines)
send_telegram(message)
print(message)
5. 코드에서 달라진 점 3가지
① 텔레그램은 requests.post로 보냅니다
8편에서는 주소 뒤에 글자를 붙여 requests.get으로 보냈습니다. 짧은 글은 그래도 되지만, 메시지에 줄바꿈이나 +, % 같은 기호가 들어가면 주소가 깨질 수 있습니다. data에 담아 post로 보내면 requests가 알아서 안전하게 바꿔 주기 때문에 여러 줄 메시지에 더 적합합니다.
② 날짜는 “최근 10일 중 최신”으로 고릅니다
beginBasDt로 10일 전부터의 데이터를 받고, max(..., key=basDt)로 가장 최근 날짜 한 건만 고릅니다. 연휴가 길어도 10일 안에는 거래일이 있으니 비어 있을 일이 거의 없습니다.
③ 한 종목이 실패해도 나머지는 보냅니다
try / except로 감싸서, 종목명을 잘못 적었거나 API가 잠시 응답하지 않아도 그 종목만 “조회 실패”로 표시하고 나머지는 정상으로 보냅니다. 자동화 코드는 한 군데 실수로 전체가 멈추지 않게 만드는 것이 중요합니다.
6. 매일 자동으로 돌리려면
코드를 파일(예: stock_alert.py)로 저장한 뒤, 윈도우 ‘작업 스케줄러’에 매일 오후 6시 실행으로 등록하면 컴퓨터가 켜져 있는 한 매일 알림이 옵니다. 작업 스케줄러 등록 방법은 다음 11편에서 단계별로 정리합니다.
한 줄 정리
9편의 시세 API로 숫자를 받고, 8편의 텔레그램 봇으로 보내면 “내 관심 종목 저녁 브리핑”이 완성됩니다. API가 다음 영업일 오후에 갱신된다는 점만 기억해서 저녁에 실행하세요.
※ 이 글은 프로그래밍 학습을 위한 정보 공유이며, 특정 종목의 매수·매도를 권유하지 않습니다. 코드 속 종목은 예시입니다.
댓글
댓글 쓰기