Files
stock-info-crawler/README.md
MH Hung 58cc979b5b refactor: modularize project structure and separate API from crawlers
- Introduce app/ package with config, services (storage, notifications), API server, and crawler modules
- Add BaseCrawler and BarronsCrawler; extract notifications and storage
- Keep enhanced_crawler.py as back-compat entry delegating to app.runner
- Add template crawler for future sites
- Update README with new structure and usage
- Extend .env.template with DATA_DIR/LOG_DIR options
2025-09-04 21:39:24 +08:00

4.8 KiB
Raw Blame History

Barron's 股票推薦爬蟲(模組化架構)

一個可擴充的爬蟲服務,內建 HTTP API 與多種通知Email/Webhook/Discord。 現已模組化API 與爬蟲核心分離,便於未來新增其他網站的爬蟲。

功能

  • 定時抓取 Barron's 股票推薦頁面
  • 只在有新內容時發送通知(可設定首次啟動也通知)
  • 內建 /health/stats/check/notify_test API
  • Docker 化部署,資料與日誌可持久化
  • 架構模組化,易於擴充其他站點

專案結構

app/
  runner.py                 # 啟動流程(載入設定、啟動 API 與爬蟲)
  config.py                 # 設定載入與 logging
  api/server.py             # Flask API
  crawlers/base.py          # BaseCrawler通用排程/比對/通知
  crawlers/barrons.py       # Barrons 爬蟲
  crawlers/template.py      # 新站點範本(複製後改名擴充)
  services/storage.py       # JSON 儲存
  services/notifications.py # Email/Webhook/Discord
enhanced_crawler.py         # 舊入口,現委派到 app.runner
Dockerfile
docker-compose.yml
requirements.txt
health_check.py
.env / .env.template
data/                      # 持久化資料(預設)
logs/                      # 持久化日誌(預設)

快速開始Docker

  1. 建立環境變數檔
cp .env.template .env
# 編輯 .env至少設定你要用到的通知方式Email/Webhook/Discord 任選)
  1. 啟動服務
docker-compose up -d
docker-compose logs -f barrons-crawler
  1. 驗證 API
curl http://localhost:8080/health
curl http://localhost:8080/stats | jq
curl http://localhost:8080/check | jq
curl "http://localhost:8080/notify_test?channel=email"    # 或 webhook/discord

本機執行(非 Docker

pip install -r requirements.txt
python enhanced_crawler.py

環境變數說明

  • 基本
    • CHECK_INTERVAL: 檢查間隔(秒),預設 300
    • LOG_LEVEL: 日誌等級,預設 INFO(可 DEBUG
    • ALWAYS_NOTIFY_ON_STARTUP: 是否在啟動後第一次就寄出目前清單true/false預設 false
  • Email可選
    • EMAIL_SMTP_SERVEREMAIL_SMTP_PORT587/465/25
    • EMAIL_SMTP_SECURITY: starttls | ssl | none預設 starttls
    • EMAIL_FROMEMAIL_TOEMAIL_USERNAMEEMAIL_PASSWORD
  • Webhook可選
    • WEBHOOK_URL: Slack/Teams Incoming Webhook URL
  • Discord可選
    • DISCORD_WEBHOOK: Discord Webhook URL
  • 進階路徑(可選)
    • DATA_DIR: 資料輸出路徑Docker 預設 /app/data;本機預設 ./data
    • LOG_DIR: 日誌輸出路徑Docker 預設 /app/logs;本機預設 ./logs

Email 使用建議:

  • Gmail 請使用「應用程式密碼」並開啟兩步驟驗證
  • 校園/企業信箱請向管理者確認 SMTP 主機、連接埠與加密方式

Web API 端點

  • GET /health: 健康檢查
  • GET /stats: 目前統計資訊(啟動時間、檢查次數、錯誤數…)
  • GET /check: 立即執行一次檢查
  • GET /notify_test?channel=email|webhook|discord: 測試通知

健康檢查與維運

  • 容器內建 HEALTHCHECK每 30 秒檢查一次 /health,連續 3 次失敗標記為不健康)
  • 常用指令
docker-compose build
docker-compose up -d
docker-compose restart
docker-compose logs -f barrons-crawler
docker-compose down

資料與日誌

  • 預設位置Docker/app/data/app/logs(已透過 volume 映射至宿主 ./data./logs
  • 檔案格式(以 Barrons 為例:data/barrons_data.json
    • last_update: ISO 時間
    • stock_picks: 文章清單title/link/hash/scraped_at
    • stats: 執行統計

擴充新站點(建議流程)

  1. 複製範本:app/crawlers/template.pyapp/crawlers/<your_site>.py
  2. 實作兩個方法:
    • fetch_page(self) -> Optional[str]:抓取 HTML
    • parse_items(self, html: str) -> List[Dict]:輸出包含 title(必要)、建議 linkhashscraped_at
  3. 啟動方式:
    • 簡單做法:為新站點建立第二個容器(複製服務段落,指定不同資料檔/埠口)
    • 進階做法:在 app/runner.py 啟動多個爬蟲與多站 API需擴充 API 路由與執行緒管理)

故障排除

  • 取不到網頁檢查網路、User-Agent、目標網站是否改版
  • Email 失敗:確認 SMTP 設定、應用程式密碼、連接埠與加密方式
  • 解析不到內容:查看日誌,更新選擇器邏輯
  • 服務無回應:檢查容器日誌與健康檢查狀態

安全建議

  • 不要把密碼放到版本控制;使用 .env 並將其列入 .gitignore
  • 適度限制通知頻率與內容,避免濫用
  • 若對外開放 API建議加上認證與 HTTPS

版本記事

  • 2025-09重構為模組化架構API 與爬蟲邏輯分離,新增擴充範本