', unsafe_allow_html=True) # 標題 st.title("🐕 台南寵物醫院查詢系統") st.markdown("---") # 側邊欄設定 with st.sidebar: st.header("🔧 查詢設定") # 區段選擇 all_sections = [1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 18, 19, 20, 22, 23, 25, 27, 29, 32, 33, 36] selected_sections = st.multiselect( "選擇要查詢的區段", options=all_sections, default=all_sections[:5], # 預設選擇前5個區段 help="選擇你想要查詢的台南市區段代碼" ) # 頁數設定 max_pages = st.slider("每個區段查詢頁數", 1, 5, 3) # 評分篩選 min_score = st.number_input( "最低評分篩選", min_value=0.0, max_value=5.0, value=4.0, step=0.1, help="只顯示評分高於此值的醫院" ) # LINE Bot 設定 st.header("📱 LINE 通知設定") channel_access_token = st.text_input( "LINE Channel Access Token", type="password", help="輸入你的 LINE Bot Channel Access Token" ) # 主要內容區域 col1, col2 = st.columns([3, 1]) with col2: search_button = st.button("🔍 開始查詢", type="primary", use_container_width=True) if search_button and selected_sections: with st.spinner("正在爬取寵物醫院資料..."): # 爬取資料 df = scrape_pet_hospitals(selected_sections, max_pages) if not df.empty: # 處理評分資料 df['評分_數值'] = pd.to_numeric(df['評分'], errors='coerce') # 篩選資料 filtered_df = df[df['評分_數值'] >= min_score].dropna(subset=['評分_數值']) # 顯示結果 st.success(f"成功爬取到 {len(df)} 家寵物醫院,篩選後顯示 {len(filtered_df)} 家") if not filtered_df.empty: # 資料統計 col1, col2, col3, col4 = st.columns(4) with col1: st.metric("總醫院數", len(df)) with col2: st.metric("篩選後數量", len(filtered_df)) with col3: st.metric("平均評分", f"{filtered_df['評分_數值'].mean():.2f}") with col4: st.metric("最高評分", f"{filtered_df['評分_數值'].max():.2f}") st.markdown("---") # 顯示表格 st.subheader("📋 查詢結果") # 先按評分排序,然後選擇要顯示的欄位 sorted_df = filtered_df.sort_values('評分_數值', ascending=False) display_df = sorted_df[['店名', '地址', '評分', '區段']] st.dataframe( display_df, use_container_width=True, hide_index=True ) # 下載功能 csv = display_df.to_csv(index=False, encoding='utf-8-sig') st.download_button( label="📥 下載 CSV 檔案", data=csv, file_name=f"台南寵物醫院_{min_score}分以上.csv", mime="text/csv" ) # LINE 發送功能 if channel_access_token: st.markdown("---") col1, col2 = st.columns([3, 1]) with col1: st.subheader("📱 發送到 LINE") with col2: if st.button("發送訊息", type="secondary"): # 準備訊息內容(取前5個結果) top_5 = display_df.head(5) message = f"台南寵物醫院推薦 (評分≥{min_score})\n\n" for _, row in top_5.iterrows(): message += f"🏥 {row['店名']}\n" message += f"📍 {row['地址']}\n" message += f"⭐ {row['評分']}\n\n" success, msg = send_line_message(message, channel_access_token) if success: st.success(msg) else: st.error(msg) else: st.warning(f"沒有找到評分 {min_score} 分以上的寵物醫院") else: st.error("未能獲取到任何資料,請檢查網路連線或稍後再試") elif search_button and not selected_sections: st.warning("請至少選擇一個區段進行查詢") st.markdown('