lin0804's picture
Update app.py
1f09029 verified
raw
history blame contribute delete
No virus
6.14 kB
import os
import requests
import pandas as pd
import json
import time
import matplotlib as mpl
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
import streamlit as st
# Streamlit 應用程式標題
st.title('電商商品價格分析 - MOMO & PChome')
# 從使用者獲取搜索關鍵字和頁數
search_keyword = st.text_input("請輸入要搜索的關鍵字:", "手機")
page_number = st.number_input("請輸入要搜索的頁數:", min_value=1, value=1)
if st.button('搜索'):
momo_data = pd.DataFrame()
pchome_data = pd.DataFrame()
# MOMO 平台搜索邏輯
momo_url = "https://apisearch.momoshop.com.tw/momoSearchCloud/moec/textSearch"
momo_headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
}
momo_payload = {
"host": "momoshop",
"flag": "searchEngine",
"data": {
"searchValue": search_keyword,
"curPage": str(page_number),
"priceS": "0",
"priceE": "9999999",
"searchType": "1"
}
}
momo_response = requests.post(momo_url, headers=momo_headers, json=momo_payload)
if momo_response.status_code == 200:
momo_data_from_api = momo_response.json()
momo_products = momo_data_from_api.get('rtnSearchData', {}).get('goodsInfoList', [])
momo_product_list = []
for product in momo_products:
name = product.get('goodsName', '')
price = product.get('goodsPrice', '')
price_str = str(price)
if '(' in price_str:
price_str = price_str.split('(')[0]
price_str = price_str.replace(',', '').replace('$', '')
try:
product_price = float(price_str)
except ValueError:
product_price = 0
momo_product_list.append({'title': name, 'price': product_price})
momo_data = pd.DataFrame(momo_product_list)
else:
st.error(f"MOMO 請求失敗,狀態碼: {momo_response.status_code}")
# PChome 平台搜索邏輯
for i in range(1, page_number + 1):
pchome_url = f'https://ecshweb.pchome.com.tw/search/v3.3/all/results?q={search_keyword}&page={i}&sort=sale/dc'
pchome_list_req = requests.get(pchome_url)
if pchome_list_req.status_code == 200:
pchome_getdata = json.loads(pchome_list_req.content)
pchome_todataFrame = pd.DataFrame(pchome_getdata['prods'])
pchome_todataFrame.rename(columns={'name': 'title'}, inplace=True)
pchome_data = pd.concat([pchome_data, pchome_todataFrame])
time.sleep(1) # Respectful delay
else:
st.error(f"PChome 請求失敗,狀態碼: {pchome_list_req.status_code}")
# 計算 MOMO 的統計數據
if not momo_data.empty:
momo_max_price = momo_data['price'].max()
momo_min_price = momo_data['price'].min()
momo_max_product = momo_data[momo_data['price'] == momo_max_price]['title'].values[0]
momo_min_product = momo_data[momo_data['price'] == momo_min_price]['title'].values[0]
momo_mean_price = momo_data['price'].mean()
st.subheader("MOMO 統計數據")
st.write(f"最高價格商品: {momo_max_product}")
st.write(f"價格: {momo_max_price}")
st.write(f"最低價格商品: {momo_min_product}")
st.write(f"價格: {momo_min_price}")
st.write(f"平均價格: {momo_mean_price:.2f}")
# 顯示 MOMO 的 DataFrame
st.write(momo_data[['title', 'price']])
# 計算 PChome 的統計數據
if not pchome_data.empty:
pchome_max_price = pchome_data['price'].max()
pchome_min_price = pchome_data['price'].min()
pchome_max_product = pchome_data[pchome_data['price'] == pchome_max_price]['title'].values[0]
pchome_min_product = pchome_data[pchome_data['price'] == pchome_min_price]['title'].values[0]
pchome_mean_price = pchome_data['price'].mean()
st.subheader("PChome 統計數據")
st.write(f"最高價格商品: {pchome_max_product}")
st.write(f"價格: {pchome_max_price}")
st.write(f"最低價格商品: {pchome_min_product}")
st.write(f"價格: {pchome_min_price}")
st.write(f"平均價格: {pchome_mean_price:.2f}")
# 顯示 PChome 的 DataFrame
st.write(pchome_data[['title', 'price']])
# 繪製合併的價格點狀圖
if not momo_data.empty or not pchome_data.empty:
# 字型設定
font_url = 'https://github.com/googlefonts/noto-cjk/raw/main/Sans/OTF/TraditionalChinese/NotoSansCJKtc-Regular.otf'
font_response = requests.get(font_url)
font_path = 'NotoSansCJKtc-Regular.otf'
with open(font_path, "wb") as font_file:
font_file.write(font_response.content)
fm.fontManager.addfont(font_path)
mpl.rc('font', family='Noto Sans CJK TC')
# 合併兩個 DataFrame
momo_data['platform'] = 'MOMO'
pchome_data['platform'] = 'PChome'
all_data = pd.concat([momo_data, pchome_data])
# 繪製價格點狀圖
fig, ax = plt.subplots(figsize=(10, 6))
for platform in all_data['platform'].unique():
platform_data = all_data[all_data['platform'] == platform]
ax.scatter(platform_data.index, platform_data['price'], label=platform, s=100, alpha=0.7)
ax.set_title(f'電商平台 "{search_keyword}" 價格比較 - MOMO & PChome', fontsize=20, fontweight='bold')
ax.set_xlabel('商品 ID', fontsize=14)
ax.set_ylabel('價格', fontsize=14)
ax.axhline(y=all_data['price'].mean(), color='red', linestyle='--', linewidth=2, label=f'總平均價格: {all_data["price"].mean():.2f}')
ax.legend(fontsize=10, loc='upper left')
ax.grid(axis='y', linestyle='--', alpha=0.5)
ax.set_facecolor('#f8f8f8')
plt.tight_layout()
st.pyplot(fig)
os.remove(font_path)
else:
st.warning("未能從 MOMO 或 PChome 獲取到數據")