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()