프로그래밍/작은 메모

간단한 나스닥 뉴스 알림

satnurn 2025. 8. 13. 20:25
반응형

이전 글과 이어 이 알림 역시 간단한 아이디어용

 

# 환경

 - window 10

 - python3.11.9

 

 

# 간단한 나스닥 실시간 뉴스 알림

 - 나스닥 정보 사이트 https://www.nasdaq.com/newsroom#press-releases 를 참고하여

파일에 포함된 긍정적인 단어를 포함한 뉴스 기사를 1분 간격으로 확인

 - 영문 뉴스 기사와 기사를 한국어로 번역하며 링크만 간단히 출력

 

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

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

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

default_pos = [
    "up", "increase", "approval", "record", "profit", "contract", "merger", "acquisition", "launch", "award"
]
default_neg = [
    "down", "loss", "lawsuit", "recall", "cut", "delay", "warning", "fraud", "decline"
]

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 NasdaqNewsWatcher:
    def __init__(self, log_widget):
        self.log_widget = log_widget
        self.running = False
        self.seen = set()
        self.translator = Translator()

    def fetch_rss_news(self):
        headers = {"User-Agent": "Mozilla/5.0"}
        resp = requests.get(url, headers=headers)
        resp.raise_for_status()

        soup = BeautifulSoup(resp.content, "xml")
        news_list = []
        for item in soup.find_all("item"):
            title = item.title.get_text(strip=True)
            link = item.link.get_text(strip=True)
            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_rss_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)  # 1분 간격

    def alert(self, item):
        try:
            translated = self.translator.translate(item['title'], src='en', dest='ko').text
        except Exception:
            translated = "(번역 실패)"
        msg = f"{item['title']} - {item['link']}\n[한글] {translated}"
        self.log(msg)

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

    def fetch_latest_news(self):
        try:
            news_items = self.fetch_rss_news()
            if news_items:
                latest = news_items[0]
                try:
                    translated = self.translator.translate(latest['title'], src='en', dest='ko').text
                except Exception:
                    translated = "(번역 실패)"
                msg = f"[Latest] {latest['title']} - {latest['link']}\n[한글] {translated}"
                self.log(msg)
            else:
                self.log("[Latest] No news found.")
        except Exception as e:
            self.log(f"Error fetching latest news: {e}")

def main():
    root = tk.Tk()
    root.title("Nasdaq Positive News Detector (with Translation)")

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

    watcher = NasdaqNewsWatcher(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()

 

 # 사용 방법

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

 $ pip install requests beautifulsoup4 lxml plyer

 $ pip install googletrans==4.0.0-rc1

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

 $ python nasdaq_watcher.py

 

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

 

 

 ** 코스피/코스닥 알림에 이어 역시 나스닥 버전도 간단하게 작성될 수 있으며 수정 및 사용 가능성 측면에서 기록함.

  (가능성 : 편의성 확대, 커스터마이징, 실시간 뉴스 정보 획득)

 

 

 

반응형