From 7e24dad8497a6604a95dc95a983082bd11bcb2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Fr=C3=B6hlich?= Date: Wed, 4 Feb 2026 09:47:39 +0100 Subject: [PATCH] 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 --- data/AlleLottozahlen.csv | 6 ++ data/learning_log.json | 91 +++++++++++++++++++++++++++ scripts/utils/update_from_api.py | 103 +++++++++++++++++++++++++++---- 3 files changed, 188 insertions(+), 12 deletions(-) diff --git a/data/AlleLottozahlen.csv b/data/AlleLottozahlen.csv index 1066528..28d0178 100644 --- a/data/AlleLottozahlen.csv +++ b/data/AlleLottozahlen.csv @@ -3089,3 +3089,9 @@ datum;Z1;Z2;Z3;Z4;Z5;Z6;SZ 2026-01-03;3;8;11;12;16;46;8 2026-01-07;15;18;29;32;36;47;0 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 diff --git a/data/learning_log.json b/data/learning_log.json index 9c033a0..6205cee 100644 --- a/data/learning_log.json +++ b/data/learning_log.json @@ -95,6 +95,97 @@ "main": 1.5, "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 + } } ] } \ No newline at end of file diff --git a/scripts/utils/update_from_api.py b/scripts/utils/update_from_api.py index 19f59ed..baabd34 100644 --- a/scripts/utils/update_from_api.py +++ b/scripts/utils/update_from_api.py @@ -31,8 +31,13 @@ class LottoAPIUpdater: self.backup_file = None self.df_existing = None - # API-Endpoints + # API-Endpoints (Lottoland zuerst, da am aktuellsten) self.apis = { + 'lottoland': { + 'url': 'https://media.lottoland.com/api/drawings/german6aus49', + 'name': 'Lottoland API', + 'parser': self._parse_lottoland + }, 'github': { 'url': 'https://johannesfriedrich.github.io/LottoNumberArchive/Lottonumbers_tidy_complete.json', 'name': 'GitHub Lotto Archive', @@ -287,6 +292,68 @@ class LottoAPIUpdater: 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: """Validiert eine Ziehung.""" try: @@ -325,19 +392,31 @@ class LottoAPIUpdater: print("=" * 70) all_draws = [] + success_count = 0 - # Versuche alle APIs (GitHub zuerst, da zuverlässig) - for api_name in ['github', 'lottoapi']: - draws = self.fetch_from_api(api_name) + # Strategie: Lottoland für aktuelle Ziehung, GitHub für Historie + # Lottoland liefert nur die neueste Ziehung, GitHub hat die komplette Historie - if draws: - all_draws.extend(draws) - print(f" ✅ {len(draws)} Ziehungen von {self.apis[api_name]['name']}") - break # Erste erfolgreiche API nutzen - else: - print(f" ⏭️ Weiter zur nächsten API...") + # 1. Versuche Lottoland für die aktuellste Ziehung + lottoland_draws = self.fetch_from_api('lottoland') + if lottoland_draws: + all_draws.extend(lottoland_draws) + success_count += 1 - 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: print("\n ❌ Keine Daten von APIs erhalten") @@ -468,7 +547,7 @@ def main(): print("=" * 70) 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: data_file = sys.argv[1]