Bremen publiziert wie Hessen nur Beschlussprotokolle (TOPs + Status-Saetze), KEINE Wortprotokolle mit Vote-Block. Daher minimaler Parser: - Drucksache + Status (angenommen/abgelehnt/ueberwiesen) - Vote-Listen bleiben leer (HB hat keine Fraktions-Detail) Anchor-Regex: "Die Buergerschaft (Landtag|Stadtbuergerschaft) <verb> <rest> <terminator>" Verb-Mapping: - "lehnt ... ab" → abgelehnt - "stimmt ... zu" → angenommen - "beschliesst ..." → angenommen - "verabschiedet ..." → angenommen - "verweist|ueberweist|leitet" → ueberwiesen - "nimmt ... Kenntnis" → uebersprungen (kein Vote) Drucksachen-Aufloesung: erst Inline-Form "(21/N)", dann Block-Form "Drucksache 21/N" rueckwaerts vom Anchor. URL-Pattern (verifiziert WP21 Sitzung 33 Land): https://www.bremische-buergerschaft.de/dokumente/wp21/land/protokoll/b21l{n4}.pdf Cron unterstuetzt jetzt {n4}-Platzhalter (4-stellig). HB Land WP21 ingestiert via direktes URL-Probing (b21l0001.pdf … b21l9999.pdf). Stadtbuergerschaft (b21s*) als Folge-Issue. Tests: 21 HB-Tests, Verifikation S33 → 20 Beschluesse extrahiert. Stand: 8 produktive Parser (NRW, BUND, BE, HH, TH, HE, SH, HB). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.3 KiB
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/<bl>.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 | ✅ produktiv (112 Votes, 39 Protokolle WP20) |
| BE | be.py |
#150 | ✅ produktiv (200 Votes, 63 Protokolle WP19) |
| HH | hh.py |
#155 | ✅ produktiv (18+ Votes WP23, Cron via Index-Scrape) |
| BB | bb.py |
#149 | 📋 Stub |
| BW | bw.py |
#151 | ⚠ Stub (Datenmodell-Inkompatibilitaet) |
| BY | by.py |
#152 | 📋 Stub |
| HB | hb.py |
#153 | ✅ produktiv (Status-Only, Beschlussprotokoll WP21, URL-Pattern direkt) |
| HE | he.py |
#154 | ✅ produktiv (Status-Only, Beschlussprotokoll WP21, Cron via Index-Scrape) |
| LSA | lsa.py |
#156 | 📋 Stub |
| MV | mv.py |
#157 | 📋 Stub |
| NI | ni.py |
#158 | 📋 Stub |
| RP | rp.py |
#159 | 📋 Stub |
| SH | sh.py |
#160 | ✅ produktiv (WP20 Sample-Tests S115/S116 grün, Cron via Index-Scrape) |
| SL | sl.py |
#161 | 📋 Stub |
| SN | sn.py |
#162 | 📋 Stub |
| TH | th.py |
#163 | ✅ produktiv (WP8 Sample, Cron mit URL-Pattern) |
Pattern fuer neue BL
- Sample-PDF/HTML/XML besorgen und Vote-Anchor-Phrasen identifizieren.
app/protokoll_parsers/<bl>.pyanlegen mitparse_protocol(path) -> list[dict]nach Vertrag aus ADR 0009.- Eintrag in
PROTOKOLL_PARSERS(in__init__.py). - Tests in
tests/test_protokoll_parsers_<bl>.py. PROTO_TARGETSinscripts/auto-ingest-protocols.shergaenzen.- 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
- MV + TH parallel (gleiche ParlDok-Plattform, Synergien)
- BUND (XML-Endpoint!) — strukturierte Daten leichter als PDF-Parser
- HE wenn HTML-Plenarprotokolle existieren
- Rest nach Bedarf
Cron-Erweiterung pro neuem BL
In scripts/auto-ingest-protocols.sh einen PROTO_TARGETS-Eintrag
ergaenzen:
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.