import requests from bs4 import BeautifulSoup import pandas as pd import gradio as gr def fetch_occupancy_data(hospital_id="10", floor=""): """ 爬取奇美醫院佔床率資料 Args: hospital_id (str): 醫院ID,默認為"10"(總院) floor (str): 樓層篩選,默認為空 Returns: tuple: (DataFrame, str) - 佔床資料的DataFrame和狀態訊息 """ # URL of the page to scrape url = f"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={hospital_id}&ffloor={floor}" try: # Send HTTP request response = requests.get(url) 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) if df.empty: return None, "無法獲取資料,請檢查網絡連接或醫院ID。" return df, "資料獲取成功!" except Exception as e: return None, f"發生錯誤: {str(e)}" def create_visualization(df): """ 建立資料視覺化圖表 Args: df (DataFrame): 佔床率資料 Returns: matplotlib.figure.Figure: 視覺化圖表 """ if df is None or df.empty: return None # 建立佔床率圖表 fig = df.plot(x='病床類別', y=['佔床數', '空床數'], kind='bar', stacked=True, figsize=(10, 6), title='奇美醫院各類病床佔用情況').get_figure() return fig def process_query(hospital_id, floor): """ 處理使用者查詢 Args: hospital_id (str): 醫院ID floor (str): 樓層篩選 Returns: tuple: (DataFrame HTML, 圖表, 訊息) """ df, message = fetch_occupancy_data(hospital_id, floor) if df is not None: fig = create_visualization(df) html_table = df.to_html(classes="table table-striped", index=False) return html_table, fig, message else: return None, None, message # 定義Gradio介面 with gr.Blocks(title="奇美醫院佔床率查詢系統") as app: gr.Markdown("# 奇美醫院佔床率查詢系統") gr.Markdown("該系統可以即時查詢奇美醫院各類病床的佔用情況") with gr.Row(): with gr.Column(scale=1): # 輸入欄位 hospital_id = gr.Dropdown( choices=[ ("總院", "10"), ("柳營分院", "20"), ("佳里分院", "30"), ("鹽埕分院", "40") ], value="10", label="選擇醫院" ) floor = gr.Textbox(label="樓層篩選 (可選)", placeholder="例如:3F、5F") query_btn = gr.Button("查詢佔床率", variant="primary") with gr.Column(scale=2): # 輸出欄位 output_message = gr.Textbox(label="查詢狀態") output_table = gr.HTML(label="佔床率資料表") output_chart = gr.Plot(label="佔床情況視覺化") # 設定查詢按鈕動作 query_btn.click( fn=process_query, inputs=[hospital_id, floor], outputs=[output_table, output_chart, output_message] ) gr.Markdown("### 使用說明") gr.Markdown(""" 1. 從下拉選單選擇要查詢的醫院 2. 可選擇性地輸入特定樓層進行篩選 3. 點擊"查詢佔床率"按鈕獲取最新資料 4. 系統會顯示表格和視覺化圖表 """) # 啟動Gradio應用 if __name__ == "__main__": app.launch()