# cSpell:ignore momo """ 更新所有監控商品的圖片 使用 i_code 從商品詳情頁直接獲取圖片 URL """ import os import sys import time from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # 設定路徑 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, BASE_DIR) from database.models import Product from utils.image_url_builder import get_product_image_url # 資料庫路徑 DB_PATH = os.path.join(BASE_DIR, 'data', 'momo_database.db') def update_all_images(batch_size: int = 100, delay: float = 0.5, start_from: int = 0): """ 更新所有監控商品的圖片 Args: batch_size: 每批處理的商品數量 delay: 每個請求之間的延遲(秒) start_from: 從第幾個商品開始處理(用於斷點續傳) """ print(f"🔄 開始更新所有監控商品的圖片(從第 {start_from + 1} 個開始)...\n") if not os.path.exists(DB_PATH): print(f"❌ 資料庫檔案不存在: {DB_PATH}") return try: engine = create_engine(f"sqlite:///{DB_PATH}") Session = sessionmaker(bind=engine) session = Session() # 查詢所有商品的總數 total_count = session.query(Product).count() print(f"📊 資料庫中共有 {total_count} 個監控商品") print(f"📦 本次將處理 {min(batch_size, total_count - start_from)} 個商品\n") # 查詢指定範圍的商品 products = session.query(Product).offset(start_from).limit(batch_size).all() if not products: print("✅ 沒有需要處理的商品!") return success_count = 0 fail_count = 0 skip_count = 0 for idx, product in enumerate(products, 1): global_idx = start_from + idx print(f"[{global_idx}/{total_count}] 處理: [{product.i_code}] {product.name[:50]}...") try: # 從商品詳情頁獲取圖片 URL image_url = get_product_image_url(product.i_code) if image_url: # 檢查圖片是否有變化 if product.image_url != image_url: product.image_url = image_url session.commit() print(f" ✅ 更新: {image_url}") success_count += 1 else: print(f" ⏭️ 相同: 圖片已是最新") skip_count += 1 else: print(f" ⚠️ 無法獲取圖片(可能已下架或不存在)") fail_count += 1 # 延遲,避免請求過快 time.sleep(delay) except Exception as e: print(f" ❌ 錯誤: {e}") fail_count += 1 session.rollback() session.close() print("\n" + "=" * 60) print("📊 本批更新結果") print("=" * 60) total = len(products) print(f"✅ 成功更新: {success_count}/{total}") print(f"⏭️ 跳過(相同): {skip_count}/{total}") print(f"❌ 失敗: {fail_count}/{total}") # 顯示進度 completed = start_from + len(products) progress = completed / total_count * 100 remaining = total_count - completed print(f"\n📈 總進度: {completed}/{total_count} ({progress:.1f}%)") if remaining > 0: print(f"⏳ 剩餘: {remaining} 個商品") print(f"\n💡 提示: 繼續執行下一批,使用參數 --start-from {completed}") else: print(f"\n🎉 所有商品已處理完成!") except Exception as e: print(f"❌ 批次更新失敗: {e}") import traceback traceback.print_exc() if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description='更新所有監控商品的圖片') parser.add_argument('--batch-size', type=int, default=100, help='每批處理的商品數量(預設: 100)') parser.add_argument('--delay', type=float, default=0.5, help='每個請求之間的延遲秒數(預設: 0.5)') parser.add_argument('--start-from', type=int, default=0, help='從第幾個商品開始處理(預設: 0)') args = parser.parse_args() update_all_images(batch_size=args.batch_size, delay=args.delay, start_from=args.start_from)