Holt automatisch alle Rechnungen deiner vergangenen Bahn-Reisen von bahn.de — und zeigt dir auf einen Blick, wie viel du wirklich für die Bahn ausgegeben hast.
Warning
Inoffizielles Tool – nicht mit der Deutschen Bahn AG verbunden. Es automatisiert lediglich Klicks in deinem eigenen, eingeloggten Kundenkonto, um deine eigenen Rechnungen herunterzuladen. Dein Passwort wird nie gespeichert oder verarbeitet — du loggst dich selbst im Browser ein. Nutzung auf eigene Verantwortung; beachte die AGB/Nutzungsbedingungen von bahn.de.
- 🔐 Sicherer Login – ein sichtbarer Browser öffnet sich, du meldest dich selbst an (inkl. 2FA/Captcha). Keine Zugangsdaten im Code, keine Cloud.
- 📥 Holt alle vergangenen Reisen – klickt automatisch „Weitere Reisen laden", bis wirklich jede Reise geladen ist.
- 🧾 Erstellt fehlende Rechnungen – ist für eine Reise noch keine Rechnung da, wird sie erst erzeugt und dann als PDF gespeichert.
- 🗂️ Kein Duplikat-Chaos – ein
manifest.jsonmerkt sich jede Rechnung per Auftragsnummer. Schon geladene Reisen werden übersprungen → Läufe sind fortsetzbar. - 💶 Beträge automatisch erkannt – liest den Gesamtbetrag aus jedem PDF und summiert alles auf.
- 📊 Dashboard – Gesamtausgaben, Anzahl Rechnungen, Zeitraum, Tabelle aller Rechnungen und eine Auswertung pro Monat.
- 🐢 Drossel-resistent – erkennt die bahn.de-Drosselung, sitzt sie aus, bremst adaptiv ab und wiederholt einzelne Reisen automatisch.
- ⏯️ Live & robust – Echtzeit-Fortschritt (SSE), Stop-Button, und der laufende Vorgang bleibt nach einem Reload / in einem neuen Tab sichtbar.
- 💻 Lokal & plattformübergreifend – läuft auf Windows, macOS und Linux. Alles bleibt auf deinem Rechner.
1. „Bei bahn.de anmelden" → Browser öffnet sich, du loggst dich ein
2. „Rechnungen abrufen" → Tool öffnet „Vergangene Reisen", lädt alle,
öffnet jede Reise, erstellt/lädt die Rechnung
3. Fertig → PDFs in data/invoices/, Beträge im Dashboard
Ein erneuter Klick auf Rechnungen abrufen lädt nur das, was noch fehlt — der Rest wird übersprungen.
Voraussetzungen: Node.js 22+
# 1. Abhängigkeiten installieren
npm install
# 2. Browser für die Automation laden (einmalig)
npm run setup # = npx playwright install chromium
# 3. Tool starten (Backend + Frontend)
npm run devDann http://localhost:5173 öffnen → „1 · Bei bahn.de anmelden" (im geöffneten Browserfenster einloggen) → „2 · Rechnungen abrufen".
Der erste Lauf dauert je nach Anzahl der Reisen ein paar Minuten (höflich gedrosselt). Jeder weitere Lauf ist schnell, weil bereits geladene Rechnungen übersprungen werden.
Alles liegt lokal im (gitignorierten) data/-Ordner:
| Pfad | Inhalt |
|---|---|
data/invoices/*.pdf |
die heruntergeladenen Rechnungen (<datum>_<auftragsnummer>.pdf) |
data/manifest.json |
Index aller Rechnungen: ID, Datum, Titel, Betrag, Dateiname |
data/browser-profile/ |
persistente Login-Session (damit du nicht jedes Mal neu einloggen musst) |
Per Umgebungsvariablen steuerbar:
| Variable | Default | Beschreibung |
|---|---|---|
PORT |
4000 |
Port des Backends |
THROTTLE_MS |
2000 |
Pause zwischen den Reisen (höher = langsamer, schont das bahn.de-Limit) |
HEADLESS |
0 |
1 = Browser unsichtbar (Login dann nur, wenn Session schon gültig ist) |
DEMO |
0 |
1 = Beispiel-Daten statt echter (für Screenshots/Vorschau) |
Beispiel (langsamer, falls bahn.de stark drosselt):
# Linux/macOS
THROTTLE_MS=4000 npm run dev
# Windows (PowerShell)
$env:THROTTLE_MS=4000; npm run dev- Kein Passwort-Handling. Der Login passiert manuell von dir im echten Browser. Das Tool wartet nur, bis du eingeloggt bist.
- Alles lokal. Rechnungen, Manifest und Login-Session bleiben auf deinem Rechner. Es gibt keinen externen Server.
data/ist gitignored — deine PDFs und deine Session landen niemals versehentlich in einem Commit.
Ohne Bahn-Konto in die Oberfläche reinschauen (liefert Beispiel-Daten aus demo/):
npm run build # Frontend bauen
DEMO=1 npm run start # bzw. $env:DEMO=1; npm run start
# → http://localhost:4000Screenshots für die README neu erzeugen:
DEMO=1 PORT=4100 npm run start -w server # in einem Terminal
node scripts/screenshot.mjs # in einem zweiten- Backend: Node.js · TypeScript · Express · Playwright (Browser-Automation) ·
pdf-parse(Betrag-Extraktion) - Frontend: React 19 · Vite 8 · Tailwind CSS 4
- Echtzeit: Server-Sent Events für den Live-Fortschritt
.
├─ server/ # Backend (Express + Playwright)
│ └─ src/
│ ├─ index.ts # API + SSE + statisches Frontend
│ ├─ bahn/
│ │ ├─ automation.ts # der gesamte Ablauf (Login → Reisen → Rechnungen)
│ │ └─ selectors.ts # ALLE bahn.de-Selektoren zentral an einem Ort
│ ├─ storage/manifest.ts # Manifest + Duplikat-Erkennung
│ └─ pdf/parse.ts # Betrag aus PDF
├─ web/ # Frontend (React + Vite + Tailwind)
├─ demo/manifest.json # Beispiel-Daten für den Demo-Modus
└─ scripts/screenshot.mjs # Playwright-Screenshots fürs README
Bricht bahn.de mal die Oberfläche um? Dann müssen i. d. R. nur die Werte in server/src/bahn/selectors.ts angepasst werden — alles andere bleibt gleich.
„DB" und „Deutsche Bahn" sind Marken der Deutschen Bahn AG. Dieses Projekt ist ein privates Hilfsmittel ohne jede Verbindung zur Deutschen Bahn AG und greift ausschließlich auf Daten zu, die dir in deinem eigenen Konto ohnehin zur Verfügung stehen. Verwende es verantwortungsvoll und im Rahmen der Nutzungsbedingungen von bahn.de.
MIT — frei verwendbar. Trag deinen Namen in die LICENSE ein, bevor du veröffentlichst.
