Files
stock-info-crawler/README.md
MH Hung f708f3bf1d feat: add OpenInsider Top-of-day crawler and multi-CRAWLER_TYPE support
New crawler: app/crawlers/openinsider_top.py\n- Scrapes three pages (sales/purchases/officer purchases)\n- Filters rows with Value/Amount >= ,000,000 (configurable via INSIDER_MIN_AMOUNT)\n- Builds concise notifications; saves to data/openinsider_top.json

Runner: support comma-separated CRAWLER_TYPE and new openinsider_top type\n- Accepts e.g., CRAWLER_TYPE=openinsider_top,openinsider,barrons\n- Preserves order, removes duplicates; warns on unknown types\n- Uses shared schedule: RUN_DAILY_AT or CHECK_INTERVAL; initial run per crawler

Entrypoint: rename enhanced_crawler.py -> main.py\n- Update Dockerfile CMD and README references

Config & docs:\n- Reorganize .env.template into clear sections with examples\n- Update .env with multi-crawler example and INSIDER_MIN_AMOUNT\n- README: document new crawler, usage, and multi-type CRAWLER_TYPE
2025-09-09 21:17:50 +08:00

152 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 股票爬蟲服務(模組化架構)
可擴充的股票爬蟲服務,內建 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) 建立環境變數檔
```bash
cp .env.template .env
# 編輯 .env至少設定你要用到的通知方式Email/Webhook/Discord 任選)
```
2) 啟動服務
```bash
docker-compose up -d
docker-compose logs -f barrons-crawler
```
3) 驗證 API
```bash
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
```bash
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_SERVER``EMAIL_SMTP_PORT`587/465/25
- `EMAIL_SMTP_SECURITY`: starttls | ssl | none預設 starttls
- `EMAIL_FROM``EMAIL_TO``EMAIL_USERNAME``EMAIL_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 次失敗標記為不健康)
- 常用指令
```bash
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.py``app/crawlers/<your_site>.py`
2) 實作兩個方法:
- `fetch_page(self) -> Optional[str]`:抓取 HTML
- `parse_items(self, html: str) -> List[Dict]`:輸出包含 `title`(必要)、建議 `link``hash``scraped_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爬蟲