89 lines
3.1 KiB
Python
89 lines
3.1 KiB
Python
"""Adapter für https://www.spielbox.de/neuheiten-neue-spiele (Joomla-Blog).
|
|
|
|
Seitenstruktur (Stand Analyse August 2026):
|
|
- Pro Beitrag ein `div.item` mit Titel-Link in `div.page-header h2 a`,
|
|
Beitragsdatum (TT.MM.JJJJ) im ersten Absatz (`p > strong`).
|
|
- Pagination über `.pagination`-Links der Form `?start=N` (6 Beiträge je
|
|
Seite) — alle Seiten werden durchlaufen, bis keine neue Seite mehr
|
|
gefunden wird.
|
|
- Verlag: Heuristik — Präfix des Titels vor dem Doppelpunkt
|
|
(z. B. „Pegasus Spiele: Next Station Berlin“); fehlt er, bleibt der
|
|
Verlag leer. Ein Autor wird auf dieser Liste nicht strukturiert
|
|
mitgeliefert.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
from .basis import QuellenAdapter, QuellenTreffer
|
|
|
|
DATUM_MUSTER = re.compile(r"(\d{2}\.\d{2}\.\d{4})")
|
|
|
|
|
|
class SpielboxQuelle(QuellenAdapter):
|
|
name = "spielbox"
|
|
anzeigename = "spielbox.de Neuheiten"
|
|
start_urls = ("https://www.spielbox.de/neuheiten-neue-spiele",)
|
|
|
|
def seite_verarbeiten(self, inhalt: bytes, url: str):
|
|
suppe = BeautifulSoup(inhalt, "html.parser")
|
|
treffer: list[QuellenTreffer] = []
|
|
for element in suppe.select("div.item"):
|
|
kopf_link = element.select_one("div.page-header h2 a") or element.find("h2")
|
|
if kopf_link is None:
|
|
continue # Strukturänderung: Beitrag überspringen, Lauf hält an
|
|
titel = kopf_link.get_text(" ", strip=True)
|
|
if not titel:
|
|
continue
|
|
href = kopf_link.get("href") if hasattr(kopf_link, "get") else None
|
|
quellen_url = _absolute_url(href, url) or url
|
|
|
|
datum = None
|
|
for absatz in element.find_all("p"):
|
|
strong = absatz.find("strong")
|
|
if strong is not None:
|
|
fund = DATUM_MUSTER.search(strong.get_text(strip=True))
|
|
if fund:
|
|
datum = fund.group(1)
|
|
break
|
|
|
|
verlag = _verlag_aus_titel(titel)
|
|
treffer.append(
|
|
QuellenTreffer(
|
|
titel=titel,
|
|
verlag=verlag,
|
|
autor=None,
|
|
erscheinungsdatum_oder_quartal=datum,
|
|
quellen_url=quellen_url,
|
|
)
|
|
)
|
|
|
|
folge_links: list[str] = []
|
|
for link in suppe.select(".pagination a[href]"):
|
|
ziel = _absolute_url(link["href"], url)
|
|
# Nur echte Paginierung dieser Liste folgen (?start=N),
|
|
# nicht den Druck-/Sprung-Links.
|
|
if ziel and "start=" in ziel:
|
|
folge_links.append(ziel)
|
|
return treffer, folge_links
|
|
|
|
|
|
def _verlag_aus_titel(titel: str) -> str | None:
|
|
"""„Verlag: Spielname“ → Verlag als Präfix vor dem Doppelpunkt."""
|
|
if ":" not in titel:
|
|
return None
|
|
praefix = titel.split(":", 1)[0].strip()
|
|
if 0 < len(praefix) <= 60:
|
|
return praefix
|
|
return None
|
|
|
|
|
|
def _absolute_url(href: str | None, basis_url: str) -> str | None:
|
|
if not href:
|
|
return None
|
|
from urllib.parse import urljoin
|
|
|
|
return urljoin(basis_url, href)
|