Plugin neuheiten: Web-Quellen-Crawler (4 Adapter, Rate-Limit, Dedup-Gate, Sync-UI)
This commit is contained in:
65
plugins/neuheiten/quellen/brettspielbox.py
Normal file
65
plugins/neuheiten/quellen/brettspielbox.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""Adapter für die Brettspielbox-Messevorschau (A-Z-Liste).
|
||||
|
||||
Seite: …/brettspiel-neuheiten-spiel-2026-herbst-2026-a-z/ (WordPress).
|
||||
|
||||
Struktur (Stand Analyse August 2026): Die komplette A-Z-Liste steht auf
|
||||
einer Seite in `div.wp-block-columns`-Blöcken — pro Buchstabe ein
|
||||
Absatz (`p`) mit dem Buchstaben bzw. „0-9“ und eine `ul` mit einem
|
||||
`li` pro Spiel im Format „Titel (Verlag)“; optionale Links im Eintrag
|
||||
zeigen auf Vorstellungs-/Rezensionsartikel und dienen als quellen_url,
|
||||
sonst gilt die Listenseite selbst.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from .basis import QuellenAdapter, QuellenTreffer
|
||||
|
||||
TITEL_VERLAG_MUSTER = re.compile(r"^\s*(.+?)\s*\(([^()]*)\)\s*$")
|
||||
|
||||
|
||||
class BrettspielboxQuelle(QuellenAdapter):
|
||||
name = "brettspielbox"
|
||||
anzeigename = "Brettspielbox Messevorschau (A–Z)"
|
||||
start_urls = (
|
||||
"https://brettspielbox.de/brettspiel-neuheiten-spiel-2026-herbst-2026-a-z/",
|
||||
)
|
||||
|
||||
def seite_verarbeiten(self, inhalt: bytes, url: str):
|
||||
suppe = BeautifulSoup(inhalt, "html.parser")
|
||||
treffer: list[QuellenTreffer] = []
|
||||
for spalte in suppe.select(".wp-block-columns"):
|
||||
for liste in spalte.find_all("ul"):
|
||||
for eintrag in liste.find_all("li"):
|
||||
text = eintrag.get_text(" ", strip=True)
|
||||
titel, verlag = _zerlege_eintrag(text)
|
||||
if not titel:
|
||||
continue
|
||||
link = eintrag.find("a", href=True)
|
||||
from urllib.parse import urljoin
|
||||
|
||||
quellen_url = (
|
||||
urljoin(url, link["href"]) if link is not None else url
|
||||
)
|
||||
treffer.append(
|
||||
QuellenTreffer(
|
||||
titel=titel,
|
||||
verlag=verlag,
|
||||
autor=None,
|
||||
erscheinungsdatum_oder_quartal=None,
|
||||
quellen_url=quellen_url,
|
||||
)
|
||||
)
|
||||
return treffer, []
|
||||
|
||||
|
||||
def _zerlege_eintrag(text: str) -> tuple[str | None, str | None]:
|
||||
"""„Titel (Verlag)“ → (Titel, Verlag); ohne Klammer nur Titel."""
|
||||
fund = TITEL_VERLAG_MUSTER.match(text)
|
||||
if fund is None:
|
||||
return (text.strip() or None), None
|
||||
verlag = fund.group(2).strip() or None
|
||||
titel = fund.group(1).strip()
|
||||
return (titel or None), verlag
|
||||
Reference in New Issue
Block a user