stocko / app.py
taeyeol's picture
Create app.py
70801f3 verified
import requests
from bs4 import BeautifulSoup
import pandas as pd
import gradio as gr
def scrape_kosdaq_info():
# ๋””๋ฒ„๊น… ๋กœ๊ทธ๋ฅผ ๋‹ด์„ ๋ฆฌ์ŠคํŠธ
debug_info = []
debug_info.append("๋ฐ์ดํ„ฐ ์Šคํฌ๋ž˜ํ•‘์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค...")
# ๋ชฉํ‘œ URL
url = "https://finance.naver.com/sise/sise_rise.naver?sosok=1"
try:
response = requests.get(url)
if response.status_code != 200:
debug_info.append(f"HTTP ์š”์ฒญ ์˜ค๋ฅ˜ ๋ฐœ์ƒ - ์ƒํƒœ ์ฝ”๋“œ: {response.status_code}")
return pd.DataFrame(), "\n".join(debug_info)
else:
debug_info.append("HTTP ์š”์ฒญ ์„ฑ๊ณต!")
except Exception as e:
debug_info.append(f"HTTP ์š”์ฒญ ์ค‘ ์˜ˆ์™ธ ๋ฐœ์ƒ: {e}")
return pd.DataFrame(), "\n".join(debug_info)
# HTML ํŒŒ์‹ฑ
html = response.text
soup = BeautifulSoup(html, "html.parser")
# ์ฝ”์Šค๋‹ฅ ์ข…๋ชฉ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ํ…Œ์ด๋ธ” ์ฐพ๊ธฐ
table = soup.find("table", class_="type_2")
if not table:
debug_info.append("ํ…Œ์ด๋ธ”์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.")
return pd.DataFrame(), "\n".join(debug_info)
rows = table.find_all("tr")
debug_info.append(f"ํ…Œ์ด๋ธ” ๋‚ด tr ํƒœ๊ทธ ๊ฐœ์ˆ˜: {len(rows)}")
data = []
# <td class="no">๊ฐ€ ์žˆ๋Š” ํ–‰์ด ์‹ค์ œ ์ข…๋ชฉ ์ •๋ณด ํ–‰
for row in rows:
num_cell = row.find("td", class_="no")
if num_cell: # ์ข…๋ชฉ ๋žญํฌ(๋ฒˆํ˜ธ)๊ฐ€ ์žˆ๋Š” ํ–‰๋งŒ ์ถ”์ถœ
cols = row.find_all("td")
# ๋””๋ฒ„๊น…์šฉ์œผ๋กœ ํ–‰ ์ •๋ณด๋ฅผ ์ถœ๋ ฅ
debug_info.append(f"ํ–‰ ์ •๋ณด: {[col.get_text(strip=True) for col in cols]}")
# ์š”์ฒญ์‚ฌํ•ญ์—์„œ ์ฃผ์–ด์ง„ ๊ตฌ์กฐ์˜ 12๊ฐœ ์ปฌ๋Ÿผ ์ •๋ณด๋ฅผ ํŒŒ์‹ฑ
if len(cols) >= 12:
rank = cols[0].get_text(strip=True)
company_name = cols[1].get_text(strip=True)
current_price = cols[2].get_text(strip=True)
change = cols[3].get_text(strip=True)
change_rate = cols[4].get_text(strip=True)
volume = cols[5].get_text(strip=True)
bid_price = cols[6].get_text(strip=True)
ask_price = cols[7].get_text(strip=True)
total_bid = cols[8].get_text(strip=True)
total_ask = cols[9].get_text(strip=True)
per_val = cols[10].get_text(strip=True)
roe_val = cols[11].get_text(strip=True)
# ์ถ”์ถœ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ์ €์žฅ
data.append([
rank, company_name, current_price,
change, change_rate, volume,
bid_price, ask_price, total_bid,
total_ask, per_val, roe_val
])
# ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„์œผ๋กœ ์ƒ์„ฑ
df = pd.DataFrame(
data,
columns=["N", "์ข…๋ชฉ๋ช…", "ํ˜„์žฌ๊ฐ€", "์ „์ผ๋น„", "๋“ฑ๋ฝ๋ฅ ", "๊ฑฐ๋ž˜๋Ÿ‰",
"๋งค์ˆ˜ํ˜ธ๊ฐ€", "๋งค๋„ํ˜ธ๊ฐ€", "๋งค์ˆ˜์ด์ž”๋Ÿ‰", "๋งค๋„์ด์ž”๋Ÿ‰", "PER", "ROE"]
)
debug_info.append(f"์Šคํฌ๋ž˜ํ•‘ ์™„๋ฃŒ. ์ด {len(df)}๊ฑด์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์ˆ˜์ง‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
return df, "\n".join(debug_info)
def main():
with gr.Blocks() as demo:
gr.Markdown("## ๋„ค์ด๋ฒ„ ์ฝ”์Šค๋‹ฅ ์ข…๋ชฉ ์ •๋ณด ์Šคํฌ๋ž˜ํ•‘")
gr.Markdown("๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋„ค์ด๋ฒ„ ์ฆ๊ถŒ(์ฝ”์Šค๋‹ฅ) ์‚ฌ์ดํŠธ์—์„œ ์ข…๋ชฉ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.")
# ๊ฒฐ๊ณผ ์ถœ๋ ฅ์šฉ ์ปดํฌ๋„ŒํŠธ
result_table = gr.Dataframe(label="์Šคํฌ๋ž˜ํ•‘ ๊ฒฐ๊ณผ")
debug_output = gr.Textbox(label="๋””๋ฒ„๊น… ๋กœ๊ทธ")
# ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์‹คํ–‰๋  ํ•จ์ˆ˜
def run_scraper():
df, debug_log = scrape_kosdaq_info()
return df, debug_log
scrape_button = gr.Button("๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ")
# ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ result_table๊ณผ debug_output์— ๊ฒฐ๊ณผ ์ถœ๋ ฅ
scrape_button.click(fn=run_scraper, inputs=[], outputs=[result_table, debug_output])
return demo
if __name__ == "__main__":
demo = main()
demo.launch()