stock / app.py
CSB261's picture
Update app.py
e435d5c verified
import os
import requests
from bs4 import BeautifulSoup
import pandas as pd
import re
import gradio as gr
from openpyxl import load_workbook
from openpyxl.styles import Font
# ๋„ค์ด๋ฒ„ ์ฆ๊ถŒ URL
url = "https://finance.naver.com/sise/sise_rise.naver?sosok=1"
# ์Šคํฌ๋ž˜ํ•‘ ํ•จ์ˆ˜
def scrape_naver_finance():
# ํŽ˜์ด์ง€ ์š”์ฒญ
response = requests.get(url)
response.encoding = 'euc-kr' # ํ•œ๊ธ€ ์ธ์ฝ”๋”ฉ ์„ค์ •
html = response.text
# BeautifulSoup์„ ์‚ฌ์šฉํ•˜์—ฌ HTML ํŒŒ์‹ฑ
soup = BeautifulSoup(html, 'html.parser')
# ํ…Œ์ด๋ธ” ์ฐพ๊ธฐ
table = soup.find("table", {"class": "type_2"})
# ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋ฆฌ์ŠคํŠธ
data = []
# ํ…Œ์ด๋ธ”์˜ ๋ชจ๋“  ํ–‰(tr) ๊ฐ€์ ธ์˜ค๊ธฐ
rows = table.find_all("tr")[2:] # ์ฒซ ๋ฒˆ์งธ ํ–‰์€ ์ œ๋ชฉ, ๋‘ ๋ฒˆ์งธ๋Š” ๋นˆ์นธ์ด๋ฏ€๋กœ ์ œ์™ธ
for row in rows:
columns = row.find_all("td")
if len(columns) > 1:
rank = columns[0].text.strip()
name = columns[1].text.strip()
price = columns[2].text.strip()
change = columns[3].text.strip()
rate = columns[4].text.strip()
volume = columns[5].text.strip()
# '์ƒํ•œ๊ฐ€', '์ƒ์Šน' ๋“ฑ์˜ ๊ธ€์”จ ์ œ๊ฑฐ
change_cleaned = re.sub(r'[^\d-]', '', change).strip()
rate_cleaned = re.sub(r'[^\d.-]', '', rate).strip()
# ๊ฐ ์—ด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฆฌ์ŠคํŠธ๋กœ ์ €์žฅ
data.append([rank, name, price, change_cleaned, rate_cleaned, volume])
# DataFrame์œผ๋กœ ๋ณ€ํ™˜
df = pd.DataFrame(data, columns=["์ˆœ์œ„", "์ข…๋ชฉ๋ช…", "ํ˜„์žฌ๊ฐ€", "์ „์ผ๋น„", "๋“ฑ๋ฝ๋ฅ ", "๊ฑฐ๋ž˜๋Ÿ‰"])
# ์ €์žฅํ•  ๋””๋ ‰ํ„ฐ๋ฆฌ ์ƒ์„ฑ (ํ•„์š”ํ•œ ๊ฒฝ์šฐ)
save_dir = "/mnt/data"
if not os.path.exists(save_dir):
os.makedirs(save_dir)
# ์—‘์…€ ํŒŒ์ผ๋กœ ์ €์žฅ
save_path = os.path.join(save_dir, "naver_top_stocks.xlsx")
df.to_excel(save_path, index=False)
# ์—‘์…€ ํŒŒ์ผ์— ์Šคํƒ€์ผ ์ถ”๊ฐ€ (์ƒ์Šน๋ฅ ์ด 20% ์ด์ƒ์ด๋ฉด ์ข…๋ชฉ๋ช…์„ ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ํ‘œ์‹œ)
workbook = load_workbook(save_path)
sheet = workbook.active
red_font = Font(color="FF0000") # ๋นจ๊ฐ„์ƒ‰ ๊ธ€์”จ์ฒด ์„ค์ •
for row in range(2, sheet.max_row + 1):
rate_value = sheet.cell(row=row, column=5).value
if rate_value and float(rate_value) >= 20.0:
sheet.cell(row=row, column=2).font = red_font # ์ข…๋ชฉ๋ช… ์ปฌ๋Ÿผ์„ ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ์„ค์ •
workbook.save(save_path)
return df, save_path
# Gradio ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜ (ํ™”๋ฉด ํ‘œ์‹œ ๋ฐ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ ๋งํฌ ์ œ๊ณต)
def get_top_stocks():
df, file_path = scrape_naver_finance()
return df, file_path
# Gradio ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ (DataFrame๊ณผ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ ์ œ๊ณต)
iface = gr.Interface(fn=get_top_stocks, inputs=None, outputs=["dataframe", "file"], title="๋„ค์ด๋ฒ„ ์ฆ๊ถŒ ์ƒ์Šน TOP ์ข…๋ชฉ")
iface.launch()