프로그래밍/작은 메모

간단한 코스피/코스닥 뉴스 알림

satnurn 2025. 8. 12. 20:30
반응형

사용 프로그램 수준은 아니고 간단한 아이디어용

 

# 환경

 - window 10

 - python3.11.9

 

 

# 간단한 네이버 실시간 뉴스 알림

 - 네이버 뉴스 기사를 참고하여 1분 간격으로 실시간 뉴스를 확인

 - 뉴스 기사와 링크만 간단히 출력

import tkinter as tk
from tkinter import scrolledtext
import threading
import time
import requests
from bs4 import BeautifulSoup
import os

POS_FILE = "keywords_positive.txt"
NEG_FILE = "keywords_negative.txt"

default_pos = [
    "상승", "호재", "계약", "수주", "실적", "합병", "인수", "신제품", "증가", "승인", "확대"
]
default_neg = [
    "하락", "악재", "소송", "감자", "리콜", "감원", "조사", "횡령", "경고"
]

if not os.path.exists(POS_FILE):
    with open(POS_FILE, "w", encoding="utf-8") as f:
        f.write("\n".join(default_pos))

if not os.path.exists(NEG_FILE):
    with open(NEG_FILE, "w", encoding="utf-8") as f:
        f.write("\n".join(default_neg))

def load_keywords(file):
    with open(file, "r", encoding="utf-8") as f:
        return [line.strip().lower() for line in f if line.strip()]

class KospiNewsWatcher:
    def __init__(self, log_widget):
        self.log_widget = log_widget
        self.running = False
        self.seen = set()

    def fetch_naver_news(self):
        headers = {"User-Agent": "Mozilla/5.0"}
        resp = requests.get(url, headers=headers)
        resp.raise_for_status()
        soup = BeautifulSoup(resp.text, "lxml")

        news_list = []
        # 최신 newarea 셀렉터 반영
        articles = soup.select("#newarea ul li a")
        for a in articles:
            title = a.get_text(strip=True)
            link = "https://finance.naver.com" + a.get("href")
            news_list.append({"title": title, "link": link})
        return news_list

    def start(self):
        if self.running:
            return
        self.running = True
        threading.Thread(target=self.loop, daemon=True).start()

    def stop(self):
        self.running = False

    def loop(self):
        while self.running:
            try:
                pos_kw = load_keywords(POS_FILE)
                neg_kw = load_keywords(NEG_FILE)
                news_items = self.fetch_naver_news()
                for item in news_items:
                    if item["link"] in self.seen:
                        continue
                    text = item["title"].lower()
                    if any(k in text for k in pos_kw) and not any(k in text for k in neg_kw):
                        self.seen.add(item["link"])
                        self.alert(item)
            except Exception as e:
                self.log(f"Error: {e}")
            time.sleep(60)

    def alert(self, item):
        msg = f"{item['title']} - {item['link']}"
        self.log(msg)

    def log(self, message):
        self.log_widget.insert(tk.END, message + "\n")
        self.log_widget.see(tk.END)

    def fetch_latest_news(self):
        try:
            news_items = self.fetch_naver_news()
            if news_items:
                latest = news_items[0]
                msg = f"[최신 뉴스] {latest['title']} - {latest['link']}"
                self.log(msg)
            else:
                self.log("[최신 뉴스] 뉴스가 없습니다.")
        except Exception as e:
            self.log(f"Error fetching latest news: {e}")

def main():
    root = tk.Tk()
    root.title("코스피/코스닥 긍정 뉴스 감지기")

    log = scrolledtext.ScrolledText(root, wrap=tk.WORD, height=20)
    log.pack(fill=tk.BOTH, expand=True)

    watcher = KospiNewsWatcher(log)

    btn_frame = tk.Frame(root)
    btn_frame.pack()

    tk.Button(btn_frame, text="Start", command=watcher.start, bg="green", fg="white").pack(side=tk.LEFT, padx=5)
    tk.Button(btn_frame, text="Stop", command=watcher.stop, bg="red", fg="white").pack(side=tk.LEFT, padx=5)
    tk.Button(btn_frame, text="Fetch Latest", command=watcher.fetch_latest_news, bg="blue", fg="white").pack(side=tk.LEFT, padx=5)

    root.mainloop()

if __name__ == "__main__":
    main()

 

 - 생성되는 "keywords_positive.txt 파일에 키워드를 수정하여 원하는 알림을 받을 수 있음.

 

 

 # 사용 방법

 - 시작 cmd (명령 프롬프트)

 $ pip install requests beautifulsoup4 lxml plyer

 - 위의 코드로 저장된 kospi_watcher.py 실행

 $ python kospi_watcher.py

 

 시작 버튼을 누르면 1분 간격으로 최신 뉴스와 링크가 출력됨.

 

 

 ** 간단하게 작성될 수 있으며 수정 및 사용 가능성 측면에서 기록함.

  (가능성 : 편의성 확대, 나스닥 버전, 커스터마이징)

 

반응형