Scraper BY: Bayern (Eigensystem, Wahl 2028-10-08) #23

Closed
opened 2026-04-08 22:22:10 +02:00 by tobias · 2 comments
Owner

Wahltermin

2028-10-08 — Bayern (BY), aktuell 19. Wahlperiode.

Backend

Feld Wert
Doku-System Eigensystem
Base-URL https://www.bayern.landtag.de
dokukratie-Scraper by
Drucksachen-Format 19/1234

Adapter-Strategie

Eigensystem — BayernAdapter ist als TODO-Stub bereits in parlamente.py Z. ~814 angelegt. Reverse-Engineering der Bayern-Doku-Suche nötig. Kein Wiederverwendungspotential mit anderen Adaptern.

Was zu tun ist

  1. Live-Backend anschauen — falls SPA, HAR-Trace einer realen Suche aus DevTools ziehen (siehe Vorgehen in #12 für ParlDok bzw. #13 für eUI).
  2. Adapter in webapp/app/parlamente.py implementieren — entweder als neue Subklasse von ParlamentAdapter oder als zweiter Registry-Eintrag eines existierenden parametrisierbaren Adapters.
  3. Eintrag in der ADAPTERS-Registry am Ende der Datei.
  4. Smoke-Test lokal: ADAPTERS["BY"].search("Schule", limit=10) liefert echte Anträge mit Datum + Fraktionen, sortiert newest-first.
  5. Aktivierung via Folge-Issue (siehe Hängt mit … zusammen unten) — dieses Issue ist nur der Adapter selbst, nicht das Indexieren der Wahlprogramme oder das Frontend-aktiv-Setzen.

Akzeptanzkriterien

  • parlamente.py::ADAPTERS["BY"] existiert und ist instanziierbar
  • search(query="Schule", limit=10) liefert ≥3 echte Drucksachen mit korrektem Datum, Fraktionen, PDF-Link
  • get_document(drucksache) für eine reale Drucksache der laufenden WP liefert das Dokument zurück
  • download_text(drucksache) extrahiert Text aus dem PDF
  • Folge-Issue für Frontend-Aktivierung verlinkt
## Wahltermin **2028-10-08** — Bayern (BY), aktuell 19. Wahlperiode. ## Backend | Feld | Wert | |---|---| | Doku-System | `Eigensystem` | | Base-URL | https://www.bayern.landtag.de | | dokukratie-Scraper | `by` | | Drucksachen-Format | `19/1234` | ## Adapter-Strategie Eigensystem — `BayernAdapter` ist als TODO-Stub bereits in `parlamente.py` Z. ~814 angelegt. Reverse-Engineering der Bayern-Doku-Suche nötig. Kein Wiederverwendungspotential mit anderen Adaptern. ## Was zu tun ist 1. Live-Backend anschauen — falls SPA, HAR-Trace einer realen Suche aus DevTools ziehen (siehe Vorgehen in #12 für ParlDok bzw. #13 für eUI). 2. Adapter in `webapp/app/parlamente.py` implementieren — entweder als neue Subklasse von `ParlamentAdapter` oder als zweiter Registry-Eintrag eines existierenden parametrisierbaren Adapters. 3. Eintrag in der `ADAPTERS`-Registry am Ende der Datei. 4. Smoke-Test lokal: `ADAPTERS["BY"].search("Schule", limit=10)` liefert echte Anträge mit Datum + Fraktionen, sortiert newest-first. 5. Aktivierung via Folge-Issue (siehe `Hängt mit … zusammen` unten) — dieses Issue ist nur der Adapter selbst, nicht das Indexieren der Wahlprogramme oder das Frontend-aktiv-Setzen. ## Akzeptanzkriterien - [ ] `parlamente.py::ADAPTERS["BY"]` existiert und ist instanziierbar - [ ] `search(query="Schule", limit=10)` liefert ≥3 echte Drucksachen mit korrektem Datum, Fraktionen, PDF-Link - [ ] `get_document(drucksache)` für eine reale Drucksache der laufenden WP liefert das Dokument zurück - [ ] `download_text(drucksache)` extrahiert Text aus dem PDF - [ ] Folge-Issue für Frontend-Aktivierung verlinkt
Author
Owner

Hinweise aus dokukratie/by.yml

HTML-Scraping mit Query-String, kein JSON-API:

  • Endpoint: https://www.bayern.landtag.de/parlament/dokumente/drucksachen/
  • Query-Parameter:
    • suchvorgangsart[] — Vorgangsart
    • wahlperiodeid[] — WP-ID
    • erfassungsdatum[start] / erfassungsdatum[end]
    • dokumentenart=Drucksache
    • anzahl_treffer=100
  • Detail-Link: .//div[@class='row result']//a[text()[contains(., 'Beratungsverlauf')]]
  • PDF: .//table[@id='basisdokument']//a[@class='vorgangDownloadlink'][1]
  • Drucksache: .//table[@id='basisdokument']//span[@class='drucksache']
  • Title: .//table[@id='basisdokument']//span[@class='betreff']
  • Originatoren: .//table[@id='dokumente']//tbody[@id='dokumente:tb']/tr/td[2]/text()
  • Pagination: .//ul[@class='pagination']/li[@class='next']

Synergie: Komplett eigenständig. BayernAdapter als TODO-Stub existiert in parlamente.py Z. ~814.

## Hinweise aus dokukratie/by.yml **HTML-Scraping mit Query-String**, kein JSON-API: - Endpoint: `https://www.bayern.landtag.de/parlament/dokumente/drucksachen/` - Query-Parameter: - `suchvorgangsart[]` — Vorgangsart - `wahlperiodeid[]` — WP-ID - `erfassungsdatum[start]` / `erfassungsdatum[end]` - `dokumentenart=Drucksache` - `anzahl_treffer=100` - Detail-Link: `.//div[@class='row result']//a[text()[contains(., 'Beratungsverlauf')]]` - PDF: `.//table[@id='basisdokument']//a[@class='vorgangDownloadlink'][1]` - Drucksache: `.//table[@id='basisdokument']//span[@class='drucksache']` - Title: `.//table[@id='basisdokument']//span[@class='betreff']` - Originatoren: `.//table[@id='dokumente']//tbody[@id='dokumente:tb']/tr/td[2]/text()` - Pagination: `.//ul[@class='pagination']/li[@class='next']` **Synergie:** Komplett eigenständig. `BayernAdapter` als TODO-Stub existiert in `parlamente.py` Z. ~814.
tobias added the
phase-3
scraper
labels 2026-04-08 23:16:36 +02:00
Author
Owner

Resolved (2026-04-10) — Adapter live

Implementation in 27ae82a. Stub durch echten BayernAdapter ersetzt.

Backend

TYPO3-Site mit ext-solr-Suche unter /parlament/dokumente/drucksachen. Server-side rendered HTML, keine SPA, keine Auth, keine Cookies. Filter direkt als URL-Query-Parameter — der freundlichste Backend der bisher implementierten Eigensystems.

Suche

GET /parlament/dokumente/drucksachen?dokumentenart=Drucksache&wahlperiodeid[]=19&q=<volltext>&sort=date&anzahl_treffer=100&page=<n>

17.598 Drucksachen in WP19 (Stand 2026-04-10), davon ~10-15% Anträge. Pro Page 100 Hits, max 3 Pages → ~30-50 Anträge nach client-seitigem Filter auf <p>Antrag …</p> (analog HE/SL).

Result-Pattern

<div class="row result">
  <h4><a href="...pdf">Drucksache Nr. 19/<NR> vom DD.MM.YYYY</a></h4>
  <p>Antrag <FRAKTION>[, <FRAKTION2>]</p>
  <h5><strong>TITLE</strong></h5>
</div>

Drei Regexen: _RE_RESULT_BLOCK, _RE_DRUCKSACHE_HEADER, _RE_TYP_FRAKTION, _RE_TITLE. Stabil und ohne BeautifulSoup-Overhead.

Drucksachen-Lookup

get_document(drucksache) nutzt q=<drucksache> — die Solr-Suche matcht die Nummer im Volltext und liefert sie als einzigen oder ersten Hit. Kein dedizierter GetById-Endpoint nötig (gleiches Pattern wie SL und HB).

Free-Voters-Disambiguation

<p>Antrag CSU, FREIE WÄHLER</p> wird durch den #55 Parteinamen-Mapper korrekt zu ["FW-BAYERN", "CSU"] aufgelöst — separat von "FREIE WÄHLER" in RP und "BVB-FW" in Brandenburg.

Akzeptanzkriterien

  • parlamente.py::ADAPTERS["BY"] existiert und ist instanziierbar
  • search("Schule", limit=5) liefert 5 echte Drucksachen mit Datum, Fraktionen, PDF-Link:
    • 19/11388 [SPD] "Gebärdensprachverbot in bayerischen Schulen…"
    • 19/11160 [FW-BAYERN, CSU] "Ausweitung der Alltagskompetenzen — Schule fürs Leben…"
    • 19/10797 [GRÜNE] "Schutzimpfungen retten (Kinder)Leben…"
    • 19/10039 [AfD] "Einführung eines Bayerischen Traditionstages…"
    • 19/10026 [AfD] "Einführung einer digitalen Schülerakte…"
  • get_document("19/11388") matcht via Volltext-Suche
  • download_text("19/11388") → 4694 Zeichen echter Antrags-Volltext
  • Newest-first sortiert (sort=date)
  • Folge-Issue für Frontend-Aktivierung: #35

Tests + Deploy

  • 185/185 lokal grün
  • Live deployed (27ae82a)

Closing.

## Resolved (2026-04-10) — Adapter live Implementation in 27ae82a. Stub durch echten BayernAdapter ersetzt. ### Backend TYPO3-Site mit ext-solr-Suche unter `/parlament/dokumente/drucksachen`. Server-side rendered HTML, keine SPA, keine Auth, keine Cookies. Filter direkt als URL-Query-Parameter — der freundlichste Backend der bisher implementierten Eigensystems. ### Suche `GET /parlament/dokumente/drucksachen?dokumentenart=Drucksache&wahlperiodeid[]=19&q=<volltext>&sort=date&anzahl_treffer=100&page=<n>` 17.598 Drucksachen in WP19 (Stand 2026-04-10), davon ~10-15% Anträge. Pro Page 100 Hits, max 3 Pages → ~30-50 Anträge nach client-seitigem Filter auf `<p>Antrag …</p>` (analog HE/SL). ### Result-Pattern ```html <div class="row result"> <h4><a href="...pdf">Drucksache Nr. 19/<NR> vom DD.MM.YYYY</a></h4> <p>Antrag <FRAKTION>[, <FRAKTION2>]</p> <h5><strong>TITLE</strong></h5> </div> ``` Drei Regexen: `_RE_RESULT_BLOCK`, `_RE_DRUCKSACHE_HEADER`, `_RE_TYP_FRAKTION`, `_RE_TITLE`. Stabil und ohne BeautifulSoup-Overhead. ### Drucksachen-Lookup `get_document(drucksache)` nutzt `q=<drucksache>` — die Solr-Suche matcht die Nummer im Volltext und liefert sie als einzigen oder ersten Hit. Kein dedizierter GetById-Endpoint nötig (gleiches Pattern wie SL und HB). ### Free-Voters-Disambiguation `<p>Antrag CSU, FREIE WÄHLER</p>` wird durch den #55 Parteinamen-Mapper korrekt zu `["FW-BAYERN", "CSU"]` aufgelöst — separat von "FREIE WÄHLER" in RP und "BVB-FW" in Brandenburg. ### Akzeptanzkriterien - [x] `parlamente.py::ADAPTERS["BY"]` existiert und ist instanziierbar - [x] `search("Schule", limit=5)` liefert 5 echte Drucksachen mit Datum, Fraktionen, PDF-Link: - 19/11388 [SPD] "Gebärdensprachverbot in bayerischen Schulen…" - 19/11160 [FW-BAYERN, CSU] "Ausweitung der Alltagskompetenzen — Schule fürs Leben…" - 19/10797 [GRÜNE] "Schutzimpfungen retten (Kinder)Leben…" - 19/10039 [AfD] "Einführung eines Bayerischen Traditionstages…" - 19/10026 [AfD] "Einführung einer digitalen Schülerakte…" - [x] `get_document("19/11388")` matcht via Volltext-Suche - [x] `download_text("19/11388")` → 4694 Zeichen echter Antrags-Volltext - [x] Newest-first sortiert (`sort=date`) - [x] Folge-Issue für Frontend-Aktivierung: #35 ### Tests + Deploy - 185/185 lokal grün - Live deployed (27ae82a) Closing.
Sign in to join this conversation.
No description provided.