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

129 lines
4.8 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.

# 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) 建立環境變數檔
```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 enhanced_crawler.py
```
## 環境變數說明
- 基本
- `CHECK_INTERVAL`: 檢查間隔(秒),預設 300
- `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`
Email 使用建議:
- Gmail 請使用「應用程式密碼」並開啟兩步驟驗證
- 校園/企業信箱請向管理者確認 SMTP 主機、連接埠與加密方式
## Web API 端點
- `GET /health`: 健康檢查
- `GET /stats`: 目前統計資訊(啟動時間、檢查次數、錯誤數…)
- `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`: 執行統計
## 擴充新站點(建議流程)
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 設定、應用程式密碼、連接埠與加密方式
- 解析不到內容:查看日誌,更新選擇器邏輯
- 服務無回應:檢查容器日誌與健康檢查狀態
## 安全建議
- 不要把密碼放到版本控制;使用 `.env` 並將其列入 `.gitignore`
- 適度限制通知頻率與內容,避免濫用
- 若對外開放 API建議加上認證與 HTTPS
## 版本記事
- 2025-09重構為模組化架構API 與爬蟲邏輯分離,新增擴充範本