PET_APP_Tainan / app.py
Roberta2024's picture
Create app.py
5b22f4e verified
raw
history blame
5.15 kB
import streamlit as st
import requests
from bs4 import BeautifulSoup
import pandas as pd
import base64
# Function to set background image
def set_background(image_file):
with open(image_file, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode()
st.markdown(
f"""
<style>
.stApp {{
background-image: url(data:image/png;base64,{encoded_string});
background-size: cover;
}}
</style>
""",
unsafe_allow_html=True
)
# Set the background image
set_background('ddog.png')
# Streamlit app title
st.title('寵物診所資訊爬蟲')
# 網址列表
urls = [
'https://www.tw-animal.com/pet/171211/c000196.html',
'https://www.tw-animal.com/pet/171211/c000186.html',
'https://www.tw-animal.com/pet/171211/c000081.html',
'https://www.tw-animal.com/pet/171211/c000848.html',
'https://www.tw-animal.com/pet/171211/c000045.html',
'https://www.tw-animal.com/pet/171211/c001166.html',
'https://www.tw-animal.com/pet/171211/c000773.html',
'https://www.tw-animal.com/pet/171211/c001038.html',
'https://www.tw-animal.com/pet/171211/c000741.html',
'https://www.tw-animal.com/pet/171211/c001451.html',
'https://www.tw-animal.com/pet/171211/c000102.html',
'https://www.tw-animal.com/pet/171211/c000757.html',
'https://www.tw-animal.com/pet/171211/c000703.html',
'https://www.tw-animal.com/pet/171211/c000481.html',
'https://www.tw-animal.com/pet/171211/c000971.html',
'https://www.tw-animal.com/pet/171211/c000187.html',
'https://www.tw-animal.com/pet/171211/c001357.html',
'https://www.tw-animal.com/pet/171211/c001065.html',
'https://www.tw-animal.com/pet/171211/c000165.html',
'https://www.tw-animal.com/pet/171211/c000217.html',
'https://www.tw-animal.com/pet/171211/c000802.html',
'https://www.tw-animal.com/pet/171211/c001034.html',
'https://www.tw-animal.com/pet/171211/c001453.html'
]
# 讓使用者輸入評分門檻
min_rating = st.slider("請選擇想篩選的最低評分", 0.0, 5.0, 4.5, 0.1)
if st.button('開始爬蟲'):
# 建立空的列表來儲存每一頁的資料
all_data = []
# 顯示進度條
progress_bar = st.progress(0)
status_text = st.empty()
# 遍歷每個網址
for i, url in enumerate(urls):
# 更新進度條和狀態文字
progress = int((i + 1) / len(urls) * 100)
progress_bar.progress(progress)
status_text.text(f'正在處理第 {i+1} 個網址,共 {len(urls)} 個')
# 發送HTTP請求獲取頁面內容
response = requests.get(url)
response.encoding = 'utf-8'
# 使用BeautifulSoup解析頁面
soup = BeautifulSoup(response.text, 'html.parser')
# 抓取標題、手機、地址和評分
title = soup.find('h1', class_='t-intro__title').get_text(strip=True)
phone = soup.find('a', href=lambda href: href and href.startswith('tel:')).get_text(strip=True)
address = soup.find('a', class_='t-font-medium').get_text(strip=True)
rating = float(soup.find('span', class_='t-intro__recommand').get_text(strip=True))
# 將評分大於或等於使用者輸入的資料存入列表
if rating >= min_rating:
all_data.append({
'標題': title,
'手機': phone,
'地址': address,
'評分': rating
})
# 將所有符合條件的資料轉換為DataFrame
df = pd.DataFrame(all_data)
# 檢查是否有符合條件的資料
if not df.empty:
# 輸出篩選後的DataFrame
st.dataframe(df)
# 提供下載 CSV 檔案的選項
csv = df.to_csv(index=False)
st.download_button(
label="下載 CSV 檔案",
data=csv,
file_name="pet_clinics.csv",
mime="text/csv",
)
else:
st.write(f"沒有找到評分大於或等於 {min_rating} 的資料。")
# 清除進度條和狀態文字
progress_bar.empty()
status_text.empty()
# LINE Notify 部分
st.header('傳送至 LINE Notify')
token = st.text_input("請輸入 LINE Notify 權杖")
if st.button('傳送至 LINE'):
if 'df' in locals() and not df.empty:
msg = df.to_string(index=False)
# 傳送 LINE Notify 訊息
def send_line_notify(token, msg):
headers = {
"Authorization": "Bearer " + token,
"Content-Type": "application/x-www-form-urlencoded"
}
params = {
"message": msg
}
r = requests.post("https://notify-api.line.me/api/notify", headers=headers, params=params)
return r.status_code
# 呼叫傳送 LINE Notify 函數
status_code = send_line_notify(token, msg)
if status_code == 200:
st.success('成功傳送至 LINE Notify!')
else:
st.error('傳送失敗,請檢查您的權杖是否正確。')
else:
st.warning('沒有資料可以傳送,請先執行爬蟲。')