File size: 5,645 Bytes
b0ecfae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
df7b02c
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import os
import requests
import pandas as pd
import matplotlib as mpl
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
import streamlit as st
import time
import json
from io import BytesIO

# Streamlit app title
st.title("MOMO & PCHOME 商品搜索和價格分析")

# 從使用者獲取搜索關鍵字和頁數
search_keyword = st.text_input("請輸入要搜索的關鍵字: ", "筆電")
page_number = st.number_input("請輸入要搜索的頁數: ", min_value=1, max_value=100, value=1, step=1)

# 如果用戶輸入了搜索關鍵字
if st.button("抓取並分析"):
    # 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 = momo_response.json().get('rtnSearchData', {}).get('goodsInfoList', [])
        momo_products = []
        for product in momo_data:
            name = product.get('goodsName', '')
            price = product.get('goodsPrice', '')
            price_str = str(price).split('(')[0].replace(',', '').replace('$', '')
            try:
                product_price = float(price_str)
            except ValueError:
                product_price = 0
            momo_products.append({'title': name, 'price': product_price, 'platform': 'MOMO'})
        momo_df = pd.DataFrame(momo_products)
        st.write("MOMO 商品數據:", momo_df)
    else:
        st.error(f"MOMO 請求失敗,狀態碼: {momo_response.status_code}")

    # PCHOME 数据抓取
    pchome_url = f'https://ecshweb.pchome.com.tw/search/v3.3/all/results?q={search_keyword}&page={page_number}&sort=sale/dc'
    pchome_response = requests.get(pchome_url)
    
    if pchome_response.status_code == 200:
        pchome_data = json.loads(pchome_response.content).get('prods', [])
        pchome_products = [{'title': item['name'], 'price': item['price'], 'platform': 'PCHOME'} for item in pchome_data]
        pchome_df = pd.DataFrame(pchome_products)
        st.write("PCHOME 商品數據:", pchome_df)
    else:
        st.error(f"PCHOME 請求失敗,狀態碼: {pchome_response.status_code}")

    # 合併兩平台數據
    if not momo_df.empty and not pchome_df.empty:
        combined_df = pd.concat([momo_df, pchome_df], ignore_index=True)
    elif not momo_df.empty:
        combined_df = momo_df
    elif not pchome_df.empty:
        combined_df = pchome_df
    else:
        combined_df = pd.DataFrame()

    if not combined_df.empty:
        st.write("合併後的商品數據:", combined_df)

        # 生成 CSV 下載連結
        csv = combined_df.to_csv(index=False).encode('utf-8')
        st.download_button(
            label="下載資料",
            data=csv,
            file_name=f"{search_keyword}_momo_pchome_data.csv",
            mime='text/csv',
        )

    # 數據分析和視覺化
    if not momo_df.empty:
        momo_avg_price = momo_df['price'].mean()
        st.write(f"MOMO 平均價格: {momo_avg_price:.2f}")
        st.write(f"MOMO 最高價格: {momo_df['price'].max():.2f}")
        st.write(f"MOMO 最低價格: {momo_df['price'].min():.2f}")

    if not pchome_df.empty:
        pchome_avg_price = pchome_df['price'].mean()
        st.write(f"PCHOME 平均價格: {pchome_avg_price:.2f}")
        st.write(f"PCHOME 最高價格: {pchome_df['price'].max():.2f}")
        st.write(f"PCHOME 最低價格: {pchome_df['price'].min():.2f}")

    # 字型設定
    font_url = "https://drive.google.com/uc?id=1eGAsTN1HBpJAkeVM57_C7ccp7hbgSz3_&export=download"
    font_response = requests.get(font_url)
    with open("TaipeiSansTCBeta-Regular.ttf", "wb") as font_file:
        font_file.write(font_response.content)
    fm.fontManager.addfont("TaipeiSansTCBeta-Regular.ttf")
    mpl.rc('font', family='Taipei Sans TC Beta')

    # MOMO 繪製價格折線圖
    if not momo_df.empty:
        fig_momo, ax_momo = plt.subplots(figsize=(15, 8))
        momo_df['price'][:70].plot(ax=ax_momo, marker='o', linestyle='-', color='skyblue', linewidth=2, markersize=8)
        plt.title(f'MOMO 電商網站上 "{search_keyword}" 的銷售價格', fontsize=20, fontweight='bold', color='navy')
        plt.axhline(y=momo_avg_price, color='red', linestyle='--', linewidth=2, label=f'參考價格: {momo_avg_price:.2f}')
        plt.legend(fontsize=12, loc='upper left')
        plt.grid(axis='y', linestyle='--', alpha=0.5)
        plt.tight_layout()
        st.pyplot(fig_momo)

    # PCHOME 繪製價格折線圖
    if not pchome_df.empty:
        fig_pchome, ax_pchome = plt.subplots(figsize=(15, 8))
        pchome_df['price'][:70].plot(ax=ax_pchome, marker='o', linestyle='-', color='skyblue', linewidth=2, markersize=8)
        plt.title(f'PCHOME 電商網站上 "{search_keyword}" 的銷售價格', fontsize=20, fontweight='bold', color='navy')
        plt.axhline(y=pchome_avg_price, color='red', linestyle='--', linewidth=2, label=f'參考價格: {pchome_avg_price:.2f}')
        plt.legend(fontsize=12, loc='upper left')
        plt.grid(axis='y', linestyle='--', alpha=0.5)
        plt.tight_layout()
        st.pyplot(fig_pchome)