214 lines
7.1 KiB
Markdown
214 lines
7.1 KiB
Markdown
# STATE: Flugpreisscanner
|
||
**Stand: 25.03.2026**
|
||
|
||
---
|
||
|
||
## Status
|
||
|
||
🚀 **In Betrieb — seit 25.02.2026**
|
||
|
||
| Komponente | Status |
|
||
|------------|--------|
|
||
| flugscanner-hub | ✅ Läuft (Docker: web + scheduler) |
|
||
| flugscanner-asia | ✅ Läuft (Docker: agent + noVNC) |
|
||
| flugscanner-mu | ⏸️ Disabled (DB) — Scraping nur Asia |
|
||
| Dashboard | ✅ http://100.92.161.97:8080 |
|
||
| Telegram Bot | ✅ @CX_HKG_Alert_bot |
|
||
|
||
---
|
||
|
||
## Kernidee
|
||
|
||
Täglich günstigste Flüge **FRA → KTI (Frankfurt → Phnom Penh)** automatisch finden.
|
||
Kabine: **Economy** · Gepäck: 1 Koffer + Handgepäck · Aufenthalt: ~2 Monate
|
||
Fokus: **Cathay Pacific (CX) via Hong Kong** — beste Preis-Leistung in Economy.
|
||
KI wertet aus: jetzt buchen oder warten?
|
||
|
||
---
|
||
|
||
## Container & Zugänge
|
||
|
||
| CT | Name | Server | Tailscale-IP | Zugang |
|
||
|----|------|--------|--------------|--------|
|
||
| 115 | `flugscanner-hub` | pve-hetzner | 100.92.161.97 | `ssh root@100.88.230.59` PW: Astral-Proxmox!2026 → `pct exec 115` |
|
||
| 115 | `flugscanner-asia` | pve-ka-1 (Kambodscha) | 100.112.190.22 | `sshpass -p astral66 ssh root@100.122.56.60` → `pct exec 115` |
|
||
| 145 | `flugscanner-mu` | helmut-pve (Muldenstein) | 100.75.182.15 | `sshpass -p astral66 ssh root@100.75.182.15` (direkt) |
|
||
|
||
**Wichtig:**
|
||
- Scraping läuft NIE von CT 115 / Hetzner aus
|
||
- Kambodscha-Node überspringt Momondo/Traveloka (Geo-Block)
|
||
- Muldenstein = deutsche IP (beste KAYAK/Momondo-Ergebnisse)
|
||
|
||
---
|
||
|
||
## Pfade Hub (CT 115, pve-hetzner)
|
||
|
||
```
|
||
/opt/flugscanner/hub/
|
||
├── docker-compose.yml
|
||
├── .env ← OPENROUTER_API_KEY, TELEGRAM_BOT_TOKEN
|
||
├── data/
|
||
│ └── flugscanner.db ← SQLite Datenbank
|
||
└── src/
|
||
├── web.py ← Flask Dashboard + API
|
||
├── scheduler.py ← Job-Koordination + Vision-KI + Telegram Bot
|
||
├── ki.py ← OpenRouter KI-Plausibilität
|
||
└── db.py ← DB-Zugriff + Init
|
||
```
|
||
|
||
## Pfade Nodes (asia + mu)
|
||
|
||
```
|
||
/opt/flugscanner/node/src/
|
||
├── worker.py ← SeleniumBase CDP Scraper (alle Scanner)
|
||
└── agent.py ← Flask API (POST /job, GET /status)
|
||
```
|
||
|
||
---
|
||
|
||
## Scanner
|
||
|
||
| Scanner | Status | Nodes | Anmerkung |
|
||
|---------|--------|-------|-----------|
|
||
| Kayak Roundtrip | ✅ Aktiv | beide | Beste Datenquelle |
|
||
| Kayak Multi-City CX via HKG | ✅ Aktiv | beide | FRA→HKG→KTI→FRA |
|
||
| Trip.com | ✅ Aktiv | beide | flightType=RT fix 21.03.2026 |
|
||
| Momondo | ✅ Aktiv | nur mu | Geo-Block aus Asien |
|
||
| Traveloka | ⚠ Nur mu | nur mu | Geo-Block aus Asien |
|
||
| Google Flights | ⚠ Eingeschränkt | beide | Consent-Probleme |
|
||
| Wego | ❌ Deaktiviert | — | |
|
||
| Skyscanner | ❌ Deaktiviert | — | Bot-Detection |
|
||
|
||
---
|
||
|
||
## KI-Pipeline
|
||
|
||
### 1. KI-Augen (OpenRouter gpt-4o-mini)
|
||
Screenshot-Analyse nach jedem Scan: PRICES_FOUND / COOKIE_BANNER / CAPTCHA / ERROR_PAGE
|
||
|
||
### 2. Kabinenklassen-Erkennung (OpenRouter gpt-4o-mini)
|
||
Vision klassifiziert Economy / Economy Light / Premium Economy / Business
|
||
|
||
### 3. Vision-Preis-Lokal (Ollama qwen3-vl:32b — kostenlos)
|
||
Nach jedem Scan: liest günstigsten **Roundtrip**-Preis aus Screenshot.
|
||
- Abweichung ≤15% → `ki_verified=1`, `ki_preis_visual` gesetzt
|
||
- Abweichung >15% → Original `plausibel=0`, neuer Eintrag `scanner=*_ki` mit KI-Preis
|
||
|
||
### 4. KI-Plausibilität (OpenRouter gpt-4o-mini)
|
||
Batch-Prüfung aller neuen Preise gegen Erfahrungswerte.
|
||
|
||
### OpenRouter
|
||
| Variable | Wert |
|
||
|----------|------|
|
||
| OPENROUTER_API_KEY | sk-or-v1-3c3... (aktualisiert 21.03.2026) |
|
||
| AI_MODEL | openai/gpt-4o-mini |
|
||
|
||
---
|
||
|
||
## Datenbank — prices Tabelle (wichtige Felder)
|
||
|
||
| Feld | Bedeutung |
|
||
|------|-----------|
|
||
| preis | Scraper-Rohpreis |
|
||
| plausibel | 1=ok, 0=Artefakt/One-Way/unplausibel, NULL=ungeprüft |
|
||
| plausi_grund | Begründung |
|
||
| ki_preis_visual | Von Vision-KI (qwen3-vl) gelesener Preis |
|
||
| ki_verified | 1 = durch Vision-KI geprüft |
|
||
| ki_verified_at | Zeitstempel der Verifikation |
|
||
| preis_korrigiert | Preis + Gepäckzuschlag falls Economy Light |
|
||
|
||
---
|
||
|
||
## Preisreferenz (Stand 21.03.2026)
|
||
|
||
**FRA → KTI Roundtrip Economy, ~2 Monate Aufenthalt**
|
||
|
||
| Metrik | Wert |
|
||
|--------|------|
|
||
| Günstigster bestätigter Roundtrip | **870 EUR** (KAYAK, 01.03.2026) |
|
||
| Realistischer Schnitt | 900–1.050 EUR |
|
||
| Obergrenze plausibel | 1.400 EUR |
|
||
| Unter 870 EUR | verdächtig (Artefakt oder One-Way) |
|
||
|
||
**Datenbasis (Stand 21.03.2026):**
|
||
- 2.107 plausible Preise gesamt
|
||
- 407 Sidebar-Artefakte bereinigt
|
||
- 252 Trip.com One-Way-Preise bereinigt
|
||
|
||
---
|
||
|
||
## Bekannte Bugs & Fixes
|
||
|
||
| Datum | Bug | Fix |
|
||
|-------|-----|-----|
|
||
| 21.03.2026 | Trip.com lieferte One-Way statt Roundtrip | `flightType=RT` in URL ergänzt |
|
||
| 21.03.2026 | KAYAK extrahierte Sidebar-Filterpreise | `_filter_sidebar_preise()` + Anker-Preis-Filter |
|
||
| 21.03.2026 | Momondo Opodo-Popup blockierte Screenshots | `_dismiss_comparison_popup()` |
|
||
| 21.03.2026 | Portainer logs als false positive in Loki | Loki-Filter erweitert |
|
||
| 21.03.2026 | OpenRouter API Key abgelaufen | Neuer Key in .env |
|
||
|
||
---
|
||
|
||
## Scan-Zeiten (Hub)
|
||
|
||
| Zeit | Was |
|
||
|------|-----|
|
||
| 06:30 / 12:30 / 18:30 | Standard-Scan (alle Jobs, alle Nodes) |
|
||
| 08:00 | Vorlauf-Scan (45/60/84 Tage vorab) |
|
||
| 07:30 | Morgenbericht Telegram |
|
||
| 20:00 | Tagesbilanz Telegram |
|
||
|
||
---
|
||
|
||
## Telegram Bot
|
||
|
||
**Bot:** @CX_HKG_Alert_bot · **Chat-ID:** 674951792
|
||
|
||
| Alert | Auslöser |
|
||
|-------|----------|
|
||
| Preis-Alert | CX < 900 EUR |
|
||
| Preisanstieg | > 50 EUR Anstieg |
|
||
| Scanner-Problem | 3x Null-Ergebnisse in Folge |
|
||
|
||
---
|
||
|
||
## Änderungslog
|
||
|
||
| Datum | Was |
|
||
|-------|-----|
|
||
| 25.02.2026 | System live geschaltet |
|
||
| 26.02.2026 | Umstellung PE → Economy, CX via HKG Hauptroute |
|
||
| 26.02.2026 | Telegram Bot eingerichtet, Doku CT999 |
|
||
| 21.03.2026 | OpenRouter API Key erneuert |
|
||
| 21.03.2026 | Trip.com One-Way Bug gefixt (flightType=RT) |
|
||
| 21.03.2026 | KAYAK Sidebar-Preis-Filter implementiert |
|
||
| 21.03.2026 | Momondo Popup-Dismisser implementiert |
|
||
| 21.03.2026 | Vision-KI Pipeline (qwen3-vl:32b lokal) eingebaut |
|
||
| 21.03.2026 | DB: ki_preis_visual + ki_verified Spalten |
|
||
| 21.03.2026 | Web-UI: KI-Verified Badge (grün/blau) |
|
||
| 21.03.2026 | 407 Sidebar + 252 One-Way Preise bereinigt |
|
||
| 21.03.2026 | Doku flugscanner-asia Zugang (via pve-ka-1) |
|
||
|
||
---
|
||
|
||
## Betrieb nur Kambodscha-Node (25.03.2026)
|
||
|
||
**Hintergrund:** Instabile Internetanbindung zum Scraping-Node in Deutschland (Muldenstein).
|
||
|
||
**Aenderung:** In `hub/data/flugscanner.db` → Tabelle `nodes`: **`flugscanner-mu`** auf `status='disabled'` gesetzt.
|
||
Alle aktiven Scans laufen nur noch ueber **`flugscanner-asia`** (CT 115 auf **pve-ka-1**, Tailscale **100.112.190.22**) — Kambodscha / Phnom-Penh-Region.
|
||
|
||
**Auswirkung:**
|
||
- **Momondo** und **Traveloka** werden nicht mehr ausgefuehrt (Geo-Block aus Asien; vorher nur sinnvoll ueber DE-IP).
|
||
- **KAYAK**, **Trip.com**, eingeschraenkt **Google Flights** bleiben auf dem Asia-Node aktiv.
|
||
|
||
**MU-Node wieder einschalten** (wenn Verbindung stabil):
|
||
```bash
|
||
cd /opt/flugscanner/hub && docker compose stop
|
||
sqlite3 data/flugscanner.db "UPDATE nodes SET status='online' WHERE name='flugscanner-mu';"
|
||
docker compose start
|
||
```
|
||
|
||
| Datum | Was |
|
||
|-------|-----|
|
||
| 25.03.2026 | flugscanner-mu disabled — Scraping nur noch Asia (Kambodscha) |
|