Test / app.py
petertulip86's picture
Update app.py
9e56881 verified
import streamlit as st
import requests
from bs4 import BeautifulSoup
import pandas as pd
import plotly.express as px
import time
def main():
st.set_page_config(page_title="奇美醫院病床占用率查詢", layout="wide")
st.title("奇美醫院病床占用率查詢系統")
st.write("此應用程式顯示奇美醫院的即時病床占用情況")
# 添加刷新按鈕
if st.button("刷新數據"):
st.cache_data.clear()
# 獲取病床數據
df = get_hospital_bed_data()
# 如果數據獲取失敗,提供示例數據
if df.empty:
st.warning("⚠️ 無法連接到奇美醫院網站。顯示示例數據以供參考。")
df = get_sample_data()
# 顯示數據
col1, col2 = st.columns([2, 3])
with col1:
st.subheader("病床占用數據表")
st.dataframe(df, use_container_width=True)
# 計算總數
total_beds = df['總床數'].sum()
total_occupied = df['佔床數'].sum()
total_available = df['空床數'].sum()
overall_rate = f"{(total_occupied / total_beds * 100):.2f}%" if total_beds > 0 else "0%"
st.subheader("總計")
total_data = pd.DataFrame({
'項目': ['總病床數', '總佔床數', '總空床數', '整體佔床率'],
'數值': [total_beds, total_occupied, total_available, overall_rate]
})
st.dataframe(total_data, use_container_width=True, hide_index=True)
with col2:
st.subheader("病床占用率視覺化")
# 創建占用率條形圖
fig = px.bar(
df,
x='病床類別',
y='佔床數',
text='佔床率',
color='佔床率',
color_continuous_scale='RdYlGn_r', # 紅(高)-黃-綠(低)色彩範圍
labels={'佔床數': '已占用病床數', '病床類別': '病床類型', '佔床率': '占用率'},
height=500
)
fig.update_layout(xaxis={'categoryorder': 'total descending'})
st.plotly_chart(fig, use_container_width=True)
# 創建餅圖顯示空床/占床比例
pie_data = pd.DataFrame({
'狀態': ['已占用', '可用'],
'數量': [total_occupied, total_available]
})
pie_fig = px.pie(
pie_data,
values='數量',
names='狀態',
color='狀態',
color_discrete_map={'已占用': 'red', '可用': 'green'},
hole=0.4
)
st.plotly_chart(pie_fig, use_container_width=True)
@st.cache_data(ttl=300) # 資料快取5分鐘
def get_hospital_bed_data():
"""獲取奇美醫院病床占用數據"""
try:
# URL of the page to scrape
url = "https://www.chimei.org.tw/%E4%BD%94%E5%BA%8A%E7%8E%87%E6%9F%A5%E8%A9%A2/%E4%BD%94%E5%BA%8A%E7%8E%87%E6%9F%A5%E8%A9%A2.aspx?ihospital=10&ffloor="
# 設置請求頭,模擬瀏覽器訪問
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'Referer': 'https://www.chimei.org.tw/'
}
# Send HTTP request with timeout and headers
response = requests.get(url, headers=headers, timeout=10)
response.encoding = 'utf-8' # Set encoding to handle Chinese characters
# Create BeautifulSoup object
soup = BeautifulSoup(response.text, 'html.parser')
# Find the target table (DG1)
target_table = soup.find('table', {'id': 'DG1'})
# Extract data from the table
data = []
if target_table:
rows = target_table.find_all('tr')
# Skip the header row
for row in rows[1:]:
cols = row.find_all('td')
if len(cols) == 5: # Ensure row has 5 columns
bed_type = cols[0].text.strip()
total_beds = int(cols[1].text.strip())
occupied_beds = int(cols[2].text.strip())
available_beds = int(cols[3].text.strip())
occupancy_rate = cols[4].text.strip()
data.append({
'病床類別': bed_type,
'總床數': total_beds,
'佔床數': occupied_beds,
'空床數': available_beds,
'佔床率': occupancy_rate
})
# Create pandas DataFrame
df = pd.DataFrame(data)
return df
except Exception as e:
st.error(f"獲取數據時發生錯誤: {e}")
return pd.DataFrame()
def get_sample_data():
"""提供示例數據,當無法從網站獲取數據時使用"""
data = [
{'病床類別': '一般病床', '總床數': 1200, '佔床數': 980, '空床數': 220, '佔床率': '81.67%'},
{'病床類別': '加護病床', '總床數': 120, '佔床數': 98, '空床數': 22, '佔床率': '81.67%'},
{'病床類別': '燒燙傷病床', '總床數': 30, '佔床數': 18, '空床數': 12, '佔床率': '60.00%'},
{'病床類別': '負壓隔離病床', '總床數': 24, '佔床數': 10, '空床數': 14, '佔床率': '41.67%'},
{'病床類別': '急診觀察病床', '總床數': 60, '佔床數': 45, '空床數': 15, '佔床率': '75.00%'},
{'病床類別': '精神科病床', '總床數': 80, '佔床數': 65, '空床數': 15, '佔床率': '81.25%'}
]
return pd.DataFrame(data)
if __name__ == "__main__":
main()