Forum: PC-Programmierung python Bahnfahrplan abfragen


von Christoph M. (mchris)


Lesenswert?

Ich will den Fahrplan der Bahn mittels Python abfrage und auswerten.
Theoretisch wäre das mit der Libray "schiene" ziemlich einfach:
1
import schiene
2
s = schiene.Schiene()
3
4
# Find connections from Mannheim Hbf to Stuttgart Hbf
5
connections = s.connections('Berlin Hbf', 'Hannover Hbf')
6
print(connections)

Praktisch geht es aber nicht. Kennt jemand da eine Möglichkeit?

von Frank D. (Firma: LAPD) (frank_s634)


Lesenswert?


: Bearbeitet durch User
von Christoph M. (mchris)


Lesenswert?

Frank D. schrieb:
> https://v6.db.transport.rest/getting-started.html

Danke, die API funktioniert.
Sie scheint aber wesentlich komplizierter als die ursprüngliche 
"schiene" Library.

Hier das gerade probierte Beispiel für die Verbindung von Stuttgart nach 
München:
1
import requests
2
import time
3
from datetime import datetime
4
5
def suche_stop(query):
6
    url = f"https://v6.db.transport.rest/locations?query={query}&results=5"
7
    try:
8
        resp = requests.get(url, timeout=10)
9
        if resp.status_code == 200:
10
            data = resp.json()
11
            print("Gefundene Stops:")
12
            for s in data:
13
                print(f"- ID: {s['id']}, Name: {s['name']}")
14
            return data[0]['id'] if data else None
15
        else:
16
            print(f"Suche-Fehler: {resp.status_code} - {resp.text}")
17
    except Exception as e:
18
        print(f"Netzwerkfehler: {e}")
19
    return None
20
21
def verbindungen(from_id, to_id, results=5, when=None):
22
    url = "https://v6.db.transport.rest/journeys"
23
    params = {
24
        'from': from_id,
25
        'to': to_id,
26
        'results': results,
27
        'language': 'de'
28
    }
29
    if when:
30
        params['when'] = when  # z.B. '2026-04-27T18:00'
31
    try:
32
        resp = requests.get(url, params=params, timeout=15)
33
        print(f"Status: {resp.status_code}")
34
        if resp.status_code == 200:
35
            data = resp.json()
36
            journeys = data.get('journeys', [])
37
            print(f"\n{len(journeys)} beste Verbindungen Stuttgart → München (Stand: {datetime.now().strftime('%H:%M')}):")
38
            for i, j in enumerate(journeys[:3], 1):  # Erste 3
39
                duration = j.get('duration', 'N/A')
40
                legs_count = len(j.get('legs', []))
41
                first_leg = j['legs'][0]
42
                dep_time = first_leg['departure']
43
                print(f"\n{i}. Dauer: {duration}, {legs_count} Etappe(n)")
44
                print(f"   Abfahrt: {dep_time} {first_leg.get('line', {}).get('name', 'Fußweg')}")
45
                print(f"   Ziel: {j['legs'][-1]['arrival']} {j['legs'][-1].get('line', {}).get('name', '')}")
46
        elif resp.status_code == 500:
47
            print("Serverfehler (500): Retry in 60s...")
48
            time.sleep(60)
49
            return verbindungen(from_id, to_id, results)
50
        else:
51
            print(f"Fehler: {resp.status_code} - {resp.text[:300]}")
52
    except Exception as e:
53
        print(f"Ausnahme: {e}")
54
55
if __name__ == "__main__":
56
    from_stop = suche_stop("Stuttgart Hbf")
57
    to_stop = suche_stop("München Hbf")
58
    if from_stop and to_stop:
59
        verbindungen(from_stop, to_stop)

von Christoph M. (mchris)


Lesenswert?

Die Anzahl der Anfragen scheint auch begrenzt zu sein. Ich habe das 
jetzt vielleicht 10x hintereinander gemacht und dann kommt:

Netzwerkfehler: HTTPSConnectionPool(host='v6.db.transport.rest', 
port=443): Read timed out. (read timeout=10)

von Frank D. (Firma: LAPD) (frank_s634)


Lesenswert?

Christoph M. schrieb:
> Die Anzahl der Anfragen scheint auch begrenzt zu sein. Ich habe
> das
> jetzt vielleicht 10x hintereinander gemacht und dann kommt:

Doku:
API status
..
Also, the new underlying APIs seem to have a much lower rate limit than 
the old HAFAS API. ⚠️

....

No API Key
You can just use the API without authentication. There's a rate limit of 
100 requests/minute set up.

von Ein T. (ein_typ)


Lesenswert?

Christoph M. schrieb:
> Frank D. schrieb:
>> https://v6.db.transport.rest/getting-started.html
>
> Danke, die API funktioniert.

Die "schiene"-Library [1] ist offenbar seit einiger Zeit nicht mehr 
gepflegt worden. Der letzte Commit ist zwar erst neun Monate her, hat 
aber lediglich den Sponsor "focsec" zur README.md und dessen Banner-PNG 
hinzugefügt.

Ein weiterer Blick in den Quellcode der Library zeigt, daß dort nicht 
die Bahn-API, sondern Web Scraping mit BeautifulSoup verwendet wird. 
Klar, das kann man natürlich machen, aber sobald der Betreiber einer 
solchen Website seinen HTML-Code ändert, funktioniert die 
Datenextraktion oft nicht mehr.

> Sie scheint aber wesentlich komplizierter als die ursprüngliche
> "schiene" Library.

Dann schreib' Dir halt was zur Vereinfachung; die APIs der Bahn sind 
aber ein bisschen... sagen wir, unhandlich. Aber wenn Du eine 
langfristig benutzbare Software entwickeln willst, wirst Du um deren 
APIs kaum herum kommen.

[1] https://github.com/kennell/schiene

von Matthias S. (dachs)


Lesenswert?

Ein T. schrieb:
> wirst Du um deren
> APIs kaum herum kommen

Und auch die werden alle paar Jahre geändert werden.

von Matthias S. (dachs)


Lesenswert?

Erschreckend fand ich auf den ersten Blick:

https://developers.deutschebahn.com/db-api-marketplace/apis/product/ris-disruptions-transporteure

RIS::Disruptions (DB Transporteure)
1.0.292
Störungsinformationen für DB Fernverkehr AG & DB Regio AG

Führt da die Abfrage "alle" nicht sofort zu DDOS-Alarm?

: Bearbeitet durch User
von Ein T. (ein_typ)


Lesenswert?

Matthias S. schrieb:
> Ein T. schrieb:
>> wirst Du um deren APIs kaum herum kommen
>
> Und auch die werden alle paar Jahre geändert werden.

Wow, man merkt: da spricht der "Fachmann". Äh, nicht. Denn die benutzen 
diese APIs für ihre eigenen Informationssysteme und für externe Partner, 
die sie bei Änderungen alle gleichzeitig updaten müßten, um nichts 
kaputt zu machen. Darum sind die APIs natürlich versioniert, so daß 
veraltete Versionen der APIS auch dann weiterhin funktionieren, wenn es 
neue gibt. So macht man das nämlich, und die OpenAPI-Angebote der Bahn 
sind unhandlich, lassen aber erkennen, daß sich dort jemand viele 
Gedanken über Themen wie Langzeitstabilität gemacht hat.

Aber jetzt, lieber Matthias, habe ich eine Frage an Dich. Nämlich: wie 
kommt man dazu, was zu einem Thema zu sagen, von dem man ganz 
offensichtlich keine Ahnung und das man sich auch keinen 
Sekundenbruchteil lang angesehen hat?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.