gwoe-antragspruefer/app/protokoll_parsers/bund.py
Dotty Dotter 7cfbd9f210 docs(#148): BUND-Stub um echte Anchor-Sprache aus WP20-Sitzung 30
Erste Probe (Sitzung 184) war Aussprache, daher 0 Beschluss-Anchors.
Sitzung 30 (572k chars, 5 angenommen-Anchors) zeigt die echte
BT-Vote-Sprache:

  'Die Beschlussempfehlung ist mit den Stimmen der Koalitions-
   fraktionen und der Fraktion Die Linke gegen die Stimmen der
   CDU/CSU-Fraktion bei Enthaltung der AfD-Fraktion angenommen.'

Pattern-Erkennung:
- Anchor-Verb 'angenommen' oder 'abgelehnt' am Satzende
- Vote-Block: 'mit den Stimmen [...] gegen die Stimmen [...]
  bei Enthaltung [...]'
- Fraktions-Phrasen: 'Fraktion X', 'X-Fraktion', 'Koalitionsfraktionen'
- Drucksachen rueckwaerts vom Anchor (oft 100+ Zeichen vorher)

Wichtig: BT-Anchor-Sprache ist viel laenger als NRW — Regex-Begrenzung
muss 200+ Zeichen tolerieren.

Sample-Sitzungen mit Beschluessen: WP20 30, 100, 150.
2026-04-28 23:15:36 +02:00

105 lines
3.7 KiB
Python

"""Bundestag (BUND) — Plenarprotokoll-Parser STUB (#106 Folge, ADR 0009).
**Status: noch nicht implementiert.** Dieser Modul-Stub enthaelt
Recherche-Findings, sodass die Implementer-Session direkt produktiv
loslegen kann. Der Stub wird **nicht** in
``app.protokoll_parsers.PROTOKOLL_PARSERS`` registriert — der
Auto-Ingest-Cron ueberspringt BUND solange.
## Recherche 2026-04-28
### URL-Pattern
Plenum-Protokoll als XML (strukturiert):
```
https://dserver.bundestag.de/btp/{wp}/{wp}{n:03}.xml
```
Beispiel WP20 Sitzung 184: ``https://dserver.bundestag.de/btp/20/20184.xml``
Plenum-Protokoll als PDF (rendert dasselbe):
```
https://dserver.bundestag.de/btp/{wp}/{wp}{n:03}.pdf
```
### XML-Format
Top-Level: ``<dbtplenarprotokoll>`` mit Children:
- ``<vorspann>`` — Sitzungsmetadaten
- ``<sitzungsverlauf>`` — Reden + Tagesordnungspunkte
- ``<anlagen>`` — Beschluss-Anlagen, namentliche Abstimmungen
- ``<rednerliste>``
Tags: ``<rede>``, ``<tagesordnungspunkt>``, ``<kommentar>`` (Regie-
Anweisungen wie "(Beifall bei der CDU/CSU)"), ``<redner>`` mit
``<fraktion>``-Untertag.
**Kein ``<abstimmung>``-Tag.** Vote-Daten muessen aus Reden + Kommentaren
extrahiert werden — gleiche Architektur wie NRW (Anchor-basiert), aber
mit ANDEREN Anchor-Phrasen.
### Vote-Anchor-Phrasen (vom NRW-Pattern abweichend!)
**Verifiziert in WP20 Sitzung 30** (572k Zeichen XML, 5 angenommen-Anchors):
```
Die Beschlussempfehlung ist mit den Stimmen der Koalitionsfraktionen
und der Fraktion Die Linke gegen die Stimmen der CDU/CSU-Fraktion bei
Enthaltung der AfD-Fraktion angenommen.
```
Pattern-Erkennung:
- Anchor-Verb: ``angenommen`` oder ``abgelehnt`` am Satzende
- Vote-Block: ``mit den Stimmen [...] gegen die Stimmen [...] bei
Enthaltung [...]``
- Fraktions-Phrasen: ``Fraktion X``, ``X-Fraktion``, ``Koalitionsfraktionen``
- Drucksachen muessen **rueckwaerts** vom Anchor gesucht werden
(oft mehrere 100 Zeichen vorher)
**Wichtig:** BT-Anchor-Sprache ist viel laenger als NRW
(``Damit ist X angenommen``, 5-30 Zeichen) — bei BT zwischen Stimm-
Block und ``angenommen`` koennen 200+ Zeichen liegen. Regex-Begrenzung
muss entsprechend grosszuegig sein.
WP20 Sitzung 184 = pure Aussprache, KEINE Beschluss-Anchors. Sample
fuer Tests: WP20-Sitzungen 30, 100, 150 (alle mit Beschluessen).
### Strukturierte Alternative — namentliche Abstimmungen
Bundestag publiziert namentliche Abstimmungen separat als Excel/XML
unter ``bundestag.de/parlament/plenum/abstimmung/abstimmung``. Pro
Abstimmung MP-level Vote-Records. Fraktions-Aggregate sind dort
extrahierbar OHNE PDF-Parsing.
**Empfehlung fuer Implementer:** statt PDF/XML-Parser bauen, lieber
``app/abgeordnetenwatch.py`` (existiert) auf Fraktions-Aggregat-Form
runterrechnen — das deckt namentliche Abstimmungen sauber ab. Nur fuer
Hammelsprung-und-Handzeichen-Abstimmungen (nicht-namentlich) muss man
das XML-Plenum parsen.
### Sample-Daten fuer Tests
- WP20 Sitzung 30: "{wp}{n:03}" → btp/20/20030.xml — enthaelt diverse
Gesetzentwurf-Beschluesse
- Sitzungen mit "namentliche Abstimmung" laut Tagesordnung sind
Goldstandard fuer Tests
### Aufwand
Geschaetzt 1-2 Tage:
- 4h Reverse-Engineering der Anchor-Sprache (mehrere Sample-Sitzungen)
- 4h Parser-Implementierung
- 4h Tests (Fixture-Pinning analog NRW 19/19-Garantie)
Folge-Issue: https://repo.toppyr.de/tobias/gwoe-antragspruefer/issues/148
"""
from __future__ import annotations
def parse_protocol(pdf_or_xml_path: str) -> list[dict]:
"""STUB — siehe Modul-Docstring."""
raise NotImplementedError(
"BUND-Plenarprotokoll-Parser ist noch nicht implementiert. "
"Siehe app/protokoll_parsers/bund.py-Docstring fuer Recherche-Findings "
"und docs/protokoll-parser-roadmap.md."
)