Skip to content

🏗 Kiến Trúc Hệ Thống (Architecture)

Tổng quan

GBS Crawler được thiết kế theo mô hình Worker-Scheduler, sử dụng Asynchronous I/O (AsyncIO) và cấu trúc phân tầng rõ ràng để dễ dàng mở rộng khi thêm nền tảng TMĐT mới.

1. Cấu trúc Các Lớp (Layered Architecture)

Lớp Lập Lịch & Điều Phối (Scheduler & Orchestration Layer)

  • main.py: Trái tim của ứng dụng. Khởi tạo APScheduler, đọc jobs.json để phân chia lịch chạy cho các Crawlers theo giờ/phút.
  • src/core/scheduler.py (nếu có): Đóng gói cấu hình thời gian chạy.
  • Bắt và bọc các ngoại lệ, gọi Notifier để báo lỗi khi Worker gặp vấn đề.

Lớp Crawler Chuyên Biệt (Platform Specific Workers)

Kế thừa từ lớp trừu tượng BaseCrawler.

  • ShopeeBaseCrawler: Kế thừa BaseCrawler. Định nghĩa cách lấy Cookie, kiểm tra Session, vượt Security check của Shopee.
  • TiktokBaseCrawler: Tương tự cho mạng TikTok Shop.

Lớp Hạ tầng Trình duyệt (Browser Infrastructure)

  • Playwright (Async): Mở trình duyệt với Persistent Context dựa trên đường dẫn thư mục profiles/[ClientName]/. Chịu trách nhiệm render DOM, bypass bot detection cơ bản.

Lớp Lưu Trữ & Thông Báo (Storage & Notification Layer)

  • src/core/notifier.py: Giao tiếp với Telegram API để bắn tin nhắn (Markdown format).
  • Lưu trữ cục bộ: File Excel, CSV, JSON vào thư mục data/[ClientName]/.

2. Mô hình Xử Lý Lỗi (Error Handling Flow)

Hệ thống sử dụng cơ chế Bubble-up Exceptions.

  1. Tại Crawler: Gặp sự cố không mong muốn (không tìm thấy XPath đăng nhập) -> Quăng SessionExpiredException.
  2. Tại run() method của BaseCrawler: Chặn ngoại lệ, ghi Log, sau đó raise lại cho luồng bên ngoài.
  3. Tại main.py: except CrawlerException as e, lấy lỗi, gọi TelegramNotifier.send_ai_prompt(e) và tiếp tục vòng lặp (không làm treo ứng dụng).

3. Sơ Đồ Hoạt Động (Flow)

mermaid
sequenceDiagram
    participant S as Scheduler
    participant M as Main
    participant C as BaseCrawler (Shopee/TikTok)
    participant B as Browser (Playwright)
    participant T as Telegram Notifier

    S->>M: Trigger Job (VD: Hara - Shopee)
    M->>C: call run()
    C->>B: Init Browser with Profile "Hara"
    B-->>C: Browser Context
    C->>B: Navigate to Dashboard
    alt if Session Expired
        B-->>C: Element Not Found (Login Page shows)
        C->>C: raise SessionExpiredException
        C-->>M: Propagate Exception
        M->>T: send_ai_prompt(Error Details)
    else if Success
        C->>B: Extract Data (DOM / Network API)
        B-->>C: Raw Data
        C->>C: Transform & Save to data/
        C-->>M: Success Return
    end

Built with DocKit Premium