股票爬蟲服務(模組化架構)

可擴充的股票爬蟲服務,內建 HTTP API 與多種通知Email/Webhook/Discord。 目前提供三類爬蟲:

  • Barron's 股票推薦
  • OpenInsider 內部人交易(支援多標的)
  • OpenInsider 當日大額內部人交易(跨三頁合併、金額過濾)

功能

  • 定時抓取(支援每 N 秒或每日固定時間)
  • 只在有新內容時發送通知(可設定首次啟動也通知)
  • 內建 /health/info/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/openinsider.py   # OpenInsider 內部人交易爬蟲(多標的)
  crawlers/template.py      # 新站點範本(複製後改名擴充)
  services/storage.py       # JSON 儲存
  services/notifications.py # Email/Webhook/Discord
 main.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 main.py

環境變數說明

  • 基本

    • CHECK_INTERVAL: 檢查間隔(秒),預設 300若設定了 RUN_DAILY_AT 則忽略)
    • RUN_DAILY_AT: 每天固定時間(例如 12:00),使用容器本機時區
    • 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
  • 爬蟲選擇與參數

    • CRAWLER_TYPE: barrons | openinsider | openinsider_top(可用逗號同時啟多種,例如:openinsider_top,openinsider
    • Barron's無額外參數
    • OpenInsider依個別股票查詢
      • 單一標的:SYMBOL=PLTR
      • 多個標的:SYMBOLS=PLTR,NVDA,TSLA
    • OpenInsider 當日大額(跨頁合併):
      • 來源頁面:
        • http://openinsider.com/top-insider-sales-of-the-day
        • http://openinsider.com/top-insider-purchases-of-the-day
        • http://openinsider.com/top-officer-purchases-of-the-day
      • 金額門檻(含千分位、自動去 $INSIDER_MIN_AMOUNT,預設 1000000

Email 使用建議:

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

Web API 端點

  • GET /health: 健康檢查
  • GET /info: 當前爬蟲資訊(多實例時回傳陣列)
  • GET /stats: 目前統計資訊(單實例為物件,多實例為 map
  • 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: 執行統計
  • OpenInsider 多標的:data/openinsider_<SYMBOL>.json

擴充新站點(建議流程)

  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 設定、應用程式密碼、連接埠與加密方式
  • Barron's 解析不到內容:查看日誌,更新選擇器邏輯
  • OpenInsider 解析不到內容:檢查 SYMBOL/SYMBOLS 是否正確,觀察是否被站方限流
  • 服務無回應:檢查容器日誌與健康檢查狀態

安全建議

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

版本記事

  • 2025-09
    • 重構為模組化架構API 與爬蟲邏輯分離
    • 新增 OpenInsider 內部人交易爬蟲與多標的支援
    • 新增 OpenInsider 當日大額內部人交易(≥$1,000,000爬蟲
Description
No description provided
Readme 102 KiB
Languages
Python 98.4%
Dockerfile 1.6%