지난 금요일에 배운 Streamlit으로 간단한 웹 앱을 만들어봤습니다.
플레이데이터 동작캠퍼스 근처 맛집을 한눈에 볼 수 있도록 정리한 페이지입니다.
- Python + Streamlit으로 화면 구성
- share.streamlit.io를 통해 무료 웹 호스팅
- 데이터는 주변 맛집도 직접 살펴볼 겸 엑셀로 CSV를 수작업 정리해서 사용했습니다.
다음 기능도 넣어보았습니다.
- 분류별 필터
- 메뉴 검색
- 네이버 지도 바로가기
- 오늘의 점심 랜덤 추천
캠퍼스 근처(서울 동작구 보라매로 87)에서 점심이 고민되는 분 계시다면, 참고해보세요 🙂
🔗 https://restaurants-dongjak-campus.streamlit.app/
(혹시 아래 링크에서 페이지가 안뜨고 가운데에 버튼만 뜨면, 그 버튼을 누르시면 재연결 됩니다!)

|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
import streamlit as st
import pandas as pd
from pathlib import Path
st.set_page_config(page_title="동작캠퍼스 근처 맛집", layout="wide")
st.title("🍽️ 동작캠퍼스 근처 맛집 정리")
st.write("서울 동작구 보라매로 87 근처 맛집 리스트")
# CSV 읽기
df = pd.read_csv("restaurants.csv", encoding="utf-8-sig")
# 결측치 처리
df = df.fillna("")
# 오늘의메뉴 랜덤 추천
import random
st.markdown(
"""
<style>
div.stButton > button {
background-color: #ef4444;
color: white;
font-size: 20px;
font-weight: bold;
padding: 14px 28px;
border-radius: 12px;
border: none;
}
div.stButton > button:hover {
background-color: #dc2626;
}
</style>
""",
unsafe_allow_html=True
)
if st.button("🍀 오늘의 점심 랜덤 추천"):
if not df.empty:
pick = df.sample(1).iloc[0]
st.markdown("## 🙆🏻♀️🙆🏻♂️ 오늘의 점심 추천")
col1, col2 = st.columns([1,2])
with col1:
image_path = str(pick["이미지"]).strip()
if image_path and Path(image_path).exists():
st.image(image_path, use_container_width=True)
with col2:
st.markdown(f"### {pick['식당명']}")
st.write(f"**분류** : {pick['분류']}")
st.write(f"**대표메뉴** : {pick['대표메뉴']}")
st.write(f"**주소** : {pick['주소']}")
link = str(pick["네이버지도링크"]).strip()
if link:
st.link_button("네이버 지도 보기", link)
st.markdown("---")
# 사이드바 필터
st.sidebar.header("조건 선택")
category_list = ["전체"] + sorted([x for x in df["분류"].unique().tolist() if x])
selected_category = st.sidebar.selectbox("분류", category_list)
keyword = st.sidebar.text_input("식당명 / 대표메뉴 검색")
sort_option = st.sidebar.selectbox(
"정렬 기준",
["기본순", "식당명 가나다순"]
)
# 필터링
filtered_df = df.copy()
if selected_category != "전체":
filtered_df = filtered_df[filtered_df["분류"] == selected_category]
if keyword:
filtered_df = filtered_df[
filtered_df["식당명"].str.contains(keyword, case=False, na=False) |
filtered_df["대표메뉴"].str.contains(keyword, case=False, na=False)
]
# 정렬
if sort_option == "식당명 가나다순":
filtered_df = filtered_df.sort_values(by="식당명", ascending=True)
st.subheader(f"검색 결과: {len(filtered_df)}곳")
# 표로 보기
with st.expander("표로 보기"):
show_df = filtered_df[["식당명", "분류", "대표메뉴", "주소"]].copy()
st.dataframe(show_df, use_container_width=True)
# 카드 형태 출력
st.subheader("맛집 카드")
if filtered_df.empty:
st.warning("조건에 맞는 식당이 없습니다.")
else:
for _, row in filtered_df.iterrows():
col1, col2 = st.columns([1, 2])
with col1:
image_path = str(row["이미지"]).strip()
if image_path and Path(image_path).exists():
st.image(image_path, use_container_width=True)
else:
st.info("이미지 없음")
with col2:
st.markdown(f"### {row['식당명']}")
st.write(f"**분류**: {row['분류']}")
st.write(f"**대표메뉴**: {row['대표메뉴']}")
st.write(f"**주소**: {row['주소']}")
link = str(row["네이버지도링크"]).strip()
if link:
st.link_button("네이버 지도 보기", link)
st.divider()
|
cs |
'Projects > Project Portfolio' 카테고리의 다른 글
| [EDA Report] IBM HR 데이터 기반 직원 이직 요인 탐색적 분석 (feat. 타자료 회귀분석) (0) | 2026.03.28 |
|---|---|
| [첫 번째 단위 프로젝트] 전기차 전환 시대, 지역별 전기차 이용 환경 분석 및 정보 제공 시스템 (0) | 2026.03.18 |
| [Web App] Streamlit 응용 : MBTI 궁합 테스트 앱 (0) | 2026.03.08 |
| [Web App] Streamlit + CSS : TOEIC VOCA 학습 앱 (0) | 2026.03.08 |