Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import requests
|
3 |
+
from bs4 import BeautifulSoup
|
4 |
+
import pandas as pd
|
5 |
+
import time
|
6 |
+
|
7 |
+
# Set page title and configuration
|
8 |
+
st.set_page_config(
|
9 |
+
page_title="醫院床位狀態查詢",
|
10 |
+
page_icon="🏥",
|
11 |
+
layout="wide"
|
12 |
+
)
|
13 |
+
|
14 |
+
# Add page header
|
15 |
+
st.title("🏥 成大醫院床位狀態查詢")
|
16 |
+
st.markdown("這個應用程式顯示成大醫院的即時床位狀態資訊")
|
17 |
+
|
18 |
+
# Function to fetch and process data
|
19 |
+
@st.cache_data(ttl=300) # Cache data for 5 minutes
|
20 |
+
def fetch_hospital_data():
|
21 |
+
# URL to fetch data from
|
22 |
+
url = "https://web.hosp.ncku.edu.tw/nckm/Bedstatus/BedStatus.aspx"
|
23 |
+
|
24 |
+
try:
|
25 |
+
# Send GET request to fetch the raw HTML content
|
26 |
+
response = requests.get(url)
|
27 |
+
response.raise_for_status() # Raise an exception for bad response codes
|
28 |
+
|
29 |
+
# Parse HTML content
|
30 |
+
soup = BeautifulSoup(response.text, 'html.parser')
|
31 |
+
|
32 |
+
# Extract the table with the data
|
33 |
+
table = soup.find('table', {'id': 'GV_EmgInsure'})
|
34 |
+
|
35 |
+
if table:
|
36 |
+
# Extract the header and rows of the table
|
37 |
+
headers = [header.text.strip() for header in table.find_all('th')]
|
38 |
+
rows = table.find_all('tr')[1:] # Skip the first row (header)
|
39 |
+
|
40 |
+
# Extract data from each row
|
41 |
+
data = []
|
42 |
+
for row in rows:
|
43 |
+
columns = row.find_all('td')
|
44 |
+
data.append([column.text.strip() for column in columns])
|
45 |
+
|
46 |
+
# Convert data to pandas DataFrame
|
47 |
+
df = pd.DataFrame(data, columns=headers)
|
48 |
+
return df, None
|
49 |
+
else:
|
50 |
+
return None, "找不到數據表格,網站可能已更改"
|
51 |
+
|
52 |
+
except requests.exceptions.RequestException as e:
|
53 |
+
return None, f"獲取數據時出錯: {str(e)}"
|
54 |
+
except Exception as e:
|
55 |
+
return None, f"處理數據時出錯: {str(e)}"
|
56 |
+
|
57 |
+
# Add refresh button and last update time display
|
58 |
+
col1, col2 = st.columns([1, 4])
|
59 |
+
with col1:
|
60 |
+
if st.button("刷新數據"):
|
61 |
+
st.cache_data.clear()
|
62 |
+
st.success("數據已刷新!")
|
63 |
+
|
64 |
+
# Display the current time
|
65 |
+
with col2:
|
66 |
+
st.write(f"最後更新時間: {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
67 |
+
|
68 |
+
# Create a spinner while loading data
|
69 |
+
with st.spinner("正在獲取最新床位數據..."):
|
70 |
+
df, error = fetch_hospital_data()
|
71 |
+
|
72 |
+
# Display error if any
|
73 |
+
if error:
|
74 |
+
st.error(error)
|
75 |
+
else:
|
76 |
+
# Display dataframe if available
|
77 |
+
if df is not None:
|
78 |
+
# Display summary metrics
|
79 |
+
st.subheader("床位狀態概覽")
|
80 |
+
try:
|
81 |
+
# This assumes there's a column with available beds info
|
82 |
+
# Adjust column names as needed based on actual data
|
83 |
+
if '可用總數' in df.columns:
|
84 |
+
total_available = df['可用總數'].astype(int).sum()
|
85 |
+
st.metric("總可用床位", total_available)
|
86 |
+
|
87 |
+
# Display the full dataset in a table
|
88 |
+
st.subheader("詳細數據")
|
89 |
+
st.dataframe(df, use_container_width=True)
|
90 |
+
|
91 |
+
# Add download button
|
92 |
+
csv = df.to_csv(index=False)
|
93 |
+
st.download_button(
|
94 |
+
label="下載CSV檔案",
|
95 |
+
data=csv,
|
96 |
+
file_name="hospital_bed_status.csv",
|
97 |
+
mime="text/csv",
|
98 |
+
)
|
99 |
+
except Exception as e:
|
100 |
+
st.warning(f"處理數據時出錯: {str(e)}")
|
101 |
+
else:
|
102 |
+
st.warning("無法獲取數據,請檢查網絡連接或稍後再試")
|
103 |
+
|
104 |
+
# Add footer
|
105 |
+
st.markdown("---")
|
106 |
+
st.markdown("數據來源: [成大醫院](https://web.hosp.ncku.edu.tw/nckm/Bedstatus/BedStatus.aspx)")
|
107 |
+
st.markdown("注意: 此應用程式僅用於演示目的,數據每5分鐘自動更新一次")
|