Add Lottoland API to Lotto update script
- Added Lottoland API (https://media.lottoland.com/api/drawings/german6aus49) for fetching the latest Lotto 6aus49 draw - Changed strategy to combine both APIs: 1. Lottoland API for the most current draw 2. GitHub Lotto Archive for historical data - Fixed default data path to use /Projekte/Lotto/data - Updated AlleLottozahlen.csv with draw from 2026-01-31 This fixes the issue where the GitHub Lotto Archive was outdated and missing recent draws. Lottoland API provides real-time results. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fcafa8b8c0
commit
7e24dad849
3 files changed
+188
-12
No files matched your search
@@ -3089,3 +3089,9 @@ datum;Z1;Z2;Z3;Z4;Z5;Z6;SZ
|
|||||||
2026-01-03;3;8;11;12;16;46;8
|
2026-01-03;3;8;11;12;16;46;8
|
||||||
2026-01-07;15;18;29;32;36;47;0
|
2026-01-07;15;18;29;32;36;47;0
|
||||||
2026-01-10;1;4;7;9;13;29;6
|
2026-01-10;1;4;7;9;13;29;6
|
||||||
|
2026-01-14;18;21;23;25;26;48;1
|
||||||
|
2026-01-17;12;21;22;37;46;49;1
|
||||||
|
2026-01-21;4;5;10;15;24;27;7
|
||||||
|
2026-01-24;1;7;28;32;47;49;1
|
||||||
|
2026-01-28;9;11;25;35;37;44;3
|
||||||
|
2026-01-31;8;19;30;37;38;49;3
|
||||||
|
@@ -95,6 +95,97 @@
|
|||||||
"main": 1.5,
|
"main": 1.5,
|
||||||
"sz_rate": 0.0
|
"sz_rate": 0.0
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-01-14T20:00:47.305269",
|
||||||
|
"draw_date": "2026-01-10",
|
||||||
|
"evaluation": {
|
||||||
|
"main": 2,
|
||||||
|
"sz": false,
|
||||||
|
"tip": 6
|
||||||
|
},
|
||||||
|
"avg_matches": {
|
||||||
|
"main": 0.7,
|
||||||
|
"sz_rate": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-01-17T20:00:49.143963",
|
||||||
|
"draw_date": "2026-01-14",
|
||||||
|
"evaluation": {
|
||||||
|
"main": 2,
|
||||||
|
"sz": false,
|
||||||
|
"tip": 6
|
||||||
|
},
|
||||||
|
"avg_matches": {
|
||||||
|
"main": 0.7,
|
||||||
|
"sz_rate": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-01-21T20:00:44.829760",
|
||||||
|
"draw_date": "2026-01-17",
|
||||||
|
"evaluation": {
|
||||||
|
"main": 2,
|
||||||
|
"sz": true,
|
||||||
|
"tip": 4
|
||||||
|
},
|
||||||
|
"avg_matches": {
|
||||||
|
"main": 1.7,
|
||||||
|
"sz_rate": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-01-24T20:00:50.265186",
|
||||||
|
"draw_date": "2026-01-21",
|
||||||
|
"evaluation": {
|
||||||
|
"main": 1,
|
||||||
|
"sz": false,
|
||||||
|
"tip": 4
|
||||||
|
},
|
||||||
|
"avg_matches": {
|
||||||
|
"main": 0.3,
|
||||||
|
"sz_rate": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-01-28T20:00:51.448284",
|
||||||
|
"draw_date": "2026-01-24",
|
||||||
|
"evaluation": {
|
||||||
|
"main": 1,
|
||||||
|
"sz": false,
|
||||||
|
"tip": 1
|
||||||
|
},
|
||||||
|
"avg_matches": {
|
||||||
|
"main": 0.5,
|
||||||
|
"sz_rate": 0.0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-01-31T20:12:26.727199",
|
||||||
|
"draw_date": "2026-01-28",
|
||||||
|
"evaluation": {
|
||||||
|
"main": 1,
|
||||||
|
"sz": true,
|
||||||
|
"tip": 9
|
||||||
|
},
|
||||||
|
"avg_matches": {
|
||||||
|
"main": 0.6,
|
||||||
|
"sz_rate": 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": "2026-02-04T09:46:35.087592",
|
||||||
|
"draw_date": "2026-01-31",
|
||||||
|
"evaluation": {
|
||||||
|
"main": 1,
|
||||||
|
"sz": true,
|
||||||
|
"tip": 9
|
||||||
|
},
|
||||||
|
"avg_matches": {
|
||||||
|
"main": 0.9,
|
||||||
|
"sz_rate": 0.1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -31,8 +31,13 @@ class LottoAPIUpdater:
|
|||||||
self.backup_file = None
|
self.backup_file = None
|
||||||
self.df_existing = None
|
self.df_existing = None
|
||||||
|
|
||||||
# API-Endpoints
|
# API-Endpoints (Lottoland zuerst, da am aktuellsten)
|
||||||
self.apis = {
|
self.apis = {
|
||||||
|
'lottoland': {
|
||||||
|
'url': 'https://media.lottoland.com/api/drawings/german6aus49',
|
||||||
|
'name': 'Lottoland API',
|
||||||
|
'parser': self._parse_lottoland
|
||||||
|
},
|
||||||
'github': {
|
'github': {
|
||||||
'url': 'https://johannesfriedrich.github.io/LottoNumberArchive/Lottonumbers_tidy_complete.json',
|
'url': 'https://johannesfriedrich.github.io/LottoNumberArchive/Lottonumbers_tidy_complete.json',
|
||||||
'name': 'GitHub Lotto Archive',
|
'name': 'GitHub Lotto Archive',
|
||||||
@@ -287,6 +292,68 @@ class LottoAPIUpdater:
|
|||||||
|
|
||||||
return draws
|
return draws
|
||||||
|
|
||||||
|
def _parse_lottoland(self, data: Dict) -> List[Dict]:
|
||||||
|
"""
|
||||||
|
Parst Lottoland API Response.
|
||||||
|
|
||||||
|
Expected format:
|
||||||
|
{
|
||||||
|
"last": {
|
||||||
|
"date": {"day": 31, "month": 1, "year": 2026, ...},
|
||||||
|
"numbers": [8, 19, 30, 37, 38, 49],
|
||||||
|
"superzahl": 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
draws = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Lottoland liefert nur die letzte Ziehung unter "last"
|
||||||
|
last_draw = data.get('last')
|
||||||
|
if not last_draw:
|
||||||
|
return draws
|
||||||
|
|
||||||
|
# Datum extrahieren
|
||||||
|
date_info = last_draw.get('date', {})
|
||||||
|
day = date_info.get('day')
|
||||||
|
month = date_info.get('month')
|
||||||
|
year = date_info.get('year')
|
||||||
|
|
||||||
|
if not all([day, month, year]):
|
||||||
|
return draws
|
||||||
|
|
||||||
|
date_obj = datetime(year, month, day)
|
||||||
|
print(f" ✅ Ziehung vom {date_obj.strftime('%Y-%m-%d')} extrahiert")
|
||||||
|
|
||||||
|
# Hauptzahlen (6 Zahlen)
|
||||||
|
numbers = sorted(last_draw.get('numbers', []))
|
||||||
|
if len(numbers) != 6:
|
||||||
|
return draws
|
||||||
|
|
||||||
|
# Superzahl
|
||||||
|
superzahl = last_draw.get('superzahl')
|
||||||
|
if superzahl is None:
|
||||||
|
return draws
|
||||||
|
|
||||||
|
draw = {
|
||||||
|
'datum': date_obj,
|
||||||
|
'Z1': numbers[0],
|
||||||
|
'Z2': numbers[1],
|
||||||
|
'Z3': numbers[2],
|
||||||
|
'Z4': numbers[3],
|
||||||
|
'Z5': numbers[4],
|
||||||
|
'Z6': numbers[5],
|
||||||
|
'SZ': int(superzahl)
|
||||||
|
}
|
||||||
|
|
||||||
|
if self._validate_draw(draw):
|
||||||
|
draws.append(draw)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ⚠️ Parse-Fehler: {e}")
|
||||||
|
|
||||||
|
return draws
|
||||||
|
|
||||||
def _validate_draw(self, draw: Dict) -> bool:
|
def _validate_draw(self, draw: Dict) -> bool:
|
||||||
"""Validiert eine Ziehung."""
|
"""Validiert eine Ziehung."""
|
||||||
try:
|
try:
|
||||||
@@ -325,19 +392,31 @@ class LottoAPIUpdater:
|
|||||||
print("=" * 70)
|
print("=" * 70)
|
||||||
|
|
||||||
all_draws = []
|
all_draws = []
|
||||||
|
success_count = 0
|
||||||
|
|
||||||
# Versuche alle APIs (GitHub zuerst, da zuverlässig)
|
# Strategie: Lottoland für aktuelle Ziehung, GitHub für Historie
|
||||||
for api_name in ['github', 'lottoapi']:
|
# Lottoland liefert nur die neueste Ziehung, GitHub hat die komplette Historie
|
||||||
draws = self.fetch_from_api(api_name)
|
|
||||||
|
|
||||||
if draws:
|
# 1. Versuche Lottoland für die aktuellste Ziehung
|
||||||
all_draws.extend(draws)
|
lottoland_draws = self.fetch_from_api('lottoland')
|
||||||
print(f" ✅ {len(draws)} Ziehungen von {self.apis[api_name]['name']}")
|
if lottoland_draws:
|
||||||
break # Erste erfolgreiche API nutzen
|
all_draws.extend(lottoland_draws)
|
||||||
else:
|
success_count += 1
|
||||||
print(f" ⏭️ Weiter zur nächsten API...")
|
|
||||||
|
|
||||||
time.sleep(1) # Pause zwischen APIs
|
time.sleep(1)
|
||||||
|
|
||||||
|
# 2. Versuche GitHub für historische Daten
|
||||||
|
github_draws = self.fetch_from_api('github')
|
||||||
|
if github_draws:
|
||||||
|
all_draws.extend(github_draws)
|
||||||
|
success_count += 1
|
||||||
|
|
||||||
|
# 3. Falls beide fehlschlagen, versuche lottoapi als Fallback
|
||||||
|
if success_count == 0:
|
||||||
|
time.sleep(1)
|
||||||
|
lottoapi_draws = self.fetch_from_api('lottoapi')
|
||||||
|
if lottoapi_draws:
|
||||||
|
all_draws.extend(lottoapi_draws)
|
||||||
|
|
||||||
if not all_draws:
|
if not all_draws:
|
||||||
print("\n ❌ Keine Daten von APIs erhalten")
|
print("\n ❌ Keine Daten von APIs erhalten")
|
||||||
@@ -468,7 +547,7 @@ def main():
|
|||||||
print("=" * 70)
|
print("=" * 70)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
default_file = "/Users/sebastianfrohlich/Library/Mobile Documents/com~apple~CloudDocs/Jupyter Notebooks/Lotto/data/AlleLottozahlen.csv"
|
default_file = "/Users/sebastianfrohlich/Projekte/Lotto/data/AlleLottozahlen.csv"
|
||||||
|
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
data_file = sys.argv[1]
|
data_file = sys.argv[1]
|
||||||
|
|||||||
Reference in new issue
Block a user