# Plenarprotokoll-Parser Roadmap pro Bundesland Stand 2026-04-28. Architektur fertig (ADR 0009), NRW-Parser produktiv, Cron-Infrastruktur (`scripts/auto-ingest-protocols.sh`) BL-erweiterbar. Pro weiterem BL ist ein eigener Parser zu implementieren — das ist deterministische Reverse-Engineering-Arbeit, keine LLM-Calls, keine Kosten. ## Stub-Module + Folge-Issues Pro BL ein Modul `app/protokoll_parsers/.py` mit Recherche-Findings im Docstring und `NotImplementedError` als Body. Stubs sind **nicht** in `PROTOKOLL_PARSERS` registriert — der Auto-Ingest-Cron ueberspringt sie. Sobald ein Parser implementiert ist, verschwindet der `NotImplementedError`- Body und der Eintrag wird in `PROTOKOLL_PARSERS` ergaenzt. | BL | Modul | Tracking-Issue | Status | |---|---|---|---| | **NRW** | `nrw.py` | (#106) | ✅ produktiv (2700+ Votes, 217+ Protokolle WP17+WP18) | | **BUND** | `bund.py` | [#148](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/148) | ✅ produktiv (112 Votes, 39 Protokolle WP20) | | **BE** | `be.py` | [#150](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/150) | ✅ produktiv (200 Votes, 63 Protokolle WP19) | | **HH** | `hh.py` | [#155](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/155) | ✅ produktiv (18+ Votes WP23, Cron via Index-Scrape) | | BB | `bb.py` | [#149](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/149) | 📋 Stub | | BW | `bw.py` | [#151](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/151) | ⚠ Stub (Datenmodell-Inkompatibilitaet) | | BY | `by.py` | [#152](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/152) | 📋 Stub | | HB | `hb.py` | [#153](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/153) | 📋 Stub | | **HE** | `he.py` | [#154](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/154) | ✅ produktiv (Status-Only, Beschlussprotokoll WP21, Cron via Index-Scrape) | | LSA | `lsa.py` | [#156](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/156) | 📋 Stub | | MV | `mv.py` | [#157](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/157) | 📋 Stub | | NI | `ni.py` | [#158](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/158) | 📋 Stub | | RP | `rp.py` | [#159](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/159) | 📋 Stub | | **SH** | `sh.py` | [#160](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/160) | ✅ produktiv (WP20 Sample-Tests S115/S116 grün, Cron via Index-Scrape) | | SL | `sl.py` | [#161](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/161) | 📋 Stub | | SN | `sn.py` | [#162](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/162) | 📋 Stub | | **TH** | `th.py` | [#163](https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/163) | ✅ produktiv (WP8 Sample, Cron mit URL-Pattern) | ## Pattern fuer neue BL 1. **Sample-PDF/HTML/XML besorgen** und Vote-Anchor-Phrasen identifizieren. 2. **`app/protokoll_parsers/.py`** anlegen mit `parse_protocol(path) -> list[dict]` nach Vertrag aus ADR 0009. 3. **Eintrag in `PROTOKOLL_PARSERS`** (in `__init__.py`). 4. **Tests** in `tests/test_protokoll_parsers_.py`. 5. **`PROTO_TARGETS`** in `scripts/auto-ingest-protocols.sh` ergaenzen. 6. **Backfill** einmal manuell laufen lassen. ## Pro Bundesland: bekannter Stand ### NRW ✅ produktiv - URL: `https://www.landtag.nrw.de/portal/WWW/dokumentenarchiv/Dokument/MMP{wp}-{n}.pdf` - Format: PDF mit deterministischen Anchor-Phrasen ("Damit ist X angenommen/abgelehnt") - Parser: `app/protokoll_parsers/nrw.py` - Tests: 38 Tests, Fixture-Garantie 19/19 auf MMP18-119 ### Bundestag (BUND) — anderer Vote-Sprache als NRW - URL: `https://dserver.bundestag.de/btp/{wp}/{wp}{n:03}.pdf` (z.B. `20184` = WP20 Sitzung 184) - Format: PDF, ~1 MB pro Sitzung, ~600k Zeichen Text. - **Vote-Anchor-Phrasen unterscheiden sich von NRW:** - Bundestag nutzt: „Wer dem Gesetzentwurf seine Zustimmung gibt, den bitte ich, sich zu erheben", „Damit ist der Gesetzentwurf in zweiter Beratung angenommen", „... mit den Stimmen der Koalition gegen die Stimmen der Opposition abgelehnt" - „angenommen" und „überwiesen" haeufig in „in zweiter Beratung angenommen" oder „zur federführenden Beratung an den Ausschuss" - Vote-Daten: bei „namentliche Abstimmung" als separate XML-Datei unter `https://dserver.bundestag.de/.../btp{wp}-{n}-namentlich.xml` (alternative datenquelle, strukturiert!) - **Empfehlung:** Statt PDF-Parsen den XML-Endpoint fuer namentliche Abstimmungen nutzen — dort liegt fraktions-aggregiertes Vote bereits als Struktur vor. - Aufwand: ~1-2 Tage ### MV — ParlDok 8.x SPA - URL-Pattern: `https://www.dokumentation.landtag-mv.de/parldok/dokument/{id}/{slug}.pdf` - Format: PDF, aber `{id}` ist nicht-vorhersagbar — braucht Listen-API von ParlDok-Suche - Workaround: Suche via Plenarprotokoll-Filter, Liste der IDs holen - Aufwand: ~2 Tage (URL-Discovery + Parser-Bau) ### Bayern (BY) — Pfad-Pattern noch zu verifizieren - Format: PDF - URL aus dokukratie-yml ziehen (nicht direkt dokumentiert) - Aufwand: ~2 Tage ### Brandenburg (BB) - URL-Pattern: `https://www.landtag.brandenburg.de/...` mit eigenem Schema - Format: PDF mit Vote-Tabellen - Aufwand: ~2-3 Tage (Tabellen-Parsing aufwendiger als reine Text-Anchors) ### Berlin (BE) - Pardok-Plattform (analog LSA, BE) - URL via Search-API - Aufwand: ~2 Tage ### Bremen (HB), Hamburg (HH), Saarland (SL) - Stadtstaaten, kleinere Landtage - Format-Recherche pro Stadt; oft PDFs mit weniger formalen Anchors - Aufwand: je ~1-2 Tage ### Hessen (HE) - Webseiten-Plenarprotokolle z.T. als HTML strukturiert (semantische Tags pro Beschluss) - Wenn HTML zugaenglich: einfacher als PDF - Sample-URL muss recherchiert werden - Aufwand: ~1-2 Tage ### Niedersachsen (NI) - nilas-Portal Login-protected (siehe `feedback_silent_excepts.md`) - Plenarprotokolle ggf. auf eigener Seite ohne Login - Aufwand: ~2-3 Tage (Login-Workaround pruefen) ### Rheinland-Pfalz (RP) - OPAL_extern, abweichend zu NRW-OPAL - PDF-URLs dokumentiert in dokukratie-yml - Aufwand: ~2 Tage ### Sachsen (SN) - ASP.NET-Webforms — Postback-Handling fuer Suche noetig - Plenarprotokoll-Liste via XML-Export - Synergie mit bestehendem `app/sn_xml_export`-Workflow moeglich - Aufwand: ~1-2 Tage ### Sachsen-Anhalt (LSA) - Padoka-Plattform (analog BE) - URL via Search-API - Aufwand: ~2 Tage ### Schleswig-Holstein (SH) - Starfinder-CGI-Backend - Format: PDF - Aufwand: ~2 Tage ### Thüringen (TH) - ParlDok-Plattform (analog MV) - Synergien mit MV-Parser hoch - Aufwand: ~1-2 Tage (nach MV) ### Baden-Württemberg (BW) - PARLIS-Eigensystem - Format: PDF - Aufwand: ~2 Tage ## Implementations-Reihenfolge nach Aufwand-Nutzen 1. **MV + TH** parallel (gleiche ParlDok-Plattform, Synergien) 2. **BUND** (XML-Endpoint!) — strukturierte Daten leichter als PDF-Parser 3. **HE** wenn HTML-Plenarprotokolle existieren 4. Rest nach Bedarf ## Cron-Erweiterung pro neuem BL In `scripts/auto-ingest-protocols.sh` einen `PROTO_TARGETS`-Eintrag ergaenzen: ```bash PROTO_TARGETS=( "NRW|18|https://www.landtag.nrw.de/.../MMP18-{n}.pdf" "BUND|20|https://dserver.bundestag.de/btp/20/20{n:03}.pdf" ... ) ``` Format-Spec: `BL_CODE|WAHLPERIODE|URL_MIT_{n}_PLACEHOLDER`. Das Skript erkennt automatisch das letzte ingestete Protokoll dieses BL/WP und inkrementiert.