auf Webseiten Modell umgestellt
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
from datetime import datetime
|
||||
import re
|
||||
from urllib.parse import urljoin
|
||||
|
||||
import requests
|
||||
@@ -10,7 +11,7 @@ from app.providers.utils import normalize_search_text
|
||||
|
||||
class BarclaysArenaProvider:
|
||||
source_name = "barclays_arena"
|
||||
events_url = "https://www.barclays-arena.de/events"
|
||||
events_url = "https://www.barclays-arena.de/events/search"
|
||||
|
||||
def search_events(
|
||||
self,
|
||||
@@ -29,73 +30,104 @@ class BarclaysArenaProvider:
|
||||
normalized_term = normalize_search_text(term)
|
||||
results: list[dict] = []
|
||||
|
||||
headings = soup.find_all("h3")
|
||||
for heading in headings:
|
||||
for heading in soup.find_all("h3"):
|
||||
title = heading.get_text(" ", strip=True)
|
||||
if not title:
|
||||
continue
|
||||
|
||||
subtitle = ""
|
||||
subtitle_el = heading.find_next("h4")
|
||||
if subtitle_el:
|
||||
subtitle = subtitle_el.get_text(" ", strip=True)
|
||||
subtitle_el = heading.find_next_sibling("h4")
|
||||
subtitle = subtitle_el.get_text(" ", strip=True) if subtitle_el else ""
|
||||
|
||||
# Keep matching local to the actual heading/subtitle pair. Wider
|
||||
# parent containers often contain several event cards.
|
||||
haystack = normalize_search_text(f"{title} {subtitle}")
|
||||
if normalized_term not in haystack:
|
||||
continue
|
||||
|
||||
date_text = self._find_previous_date_text(heading)
|
||||
event_date = self._parse_german_date(date_text)
|
||||
|
||||
link = heading.find_previous("a", href=True)
|
||||
if link is None:
|
||||
detail_link = self._find_card_link(heading)
|
||||
if detail_link is None:
|
||||
continue
|
||||
|
||||
date_text = self._find_card_date_text(heading)
|
||||
event_date = self._parse_german_date(date_text)
|
||||
href = detail_link["href"]
|
||||
|
||||
results.append(
|
||||
{
|
||||
"external_id": link["href"],
|
||||
"external_id": href,
|
||||
"title": title,
|
||||
"matched_term": term,
|
||||
"venue_name": "Barclays Arena",
|
||||
"city": "Hamburg",
|
||||
"country_code": "DE",
|
||||
"event_date": event_date,
|
||||
"ticket_url": urljoin(self.events_url, link["href"]),
|
||||
"ticket_url": urljoin(self.events_url, href),
|
||||
"image_url": None,
|
||||
"raw_payload": {
|
||||
"title": title,
|
||||
"subtitle": subtitle,
|
||||
"date_text": date_text,
|
||||
"href": link["href"],
|
||||
"href": href,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
unique_results: dict[str, dict] = {}
|
||||
for result in results:
|
||||
unique_results[result["external_id"]] = result
|
||||
|
||||
self.last_status = "ok"
|
||||
self.last_message = (
|
||||
f"Barclays Arena returned {len(results)} matched events for term '{term}'."
|
||||
f"Barclays Arena returned {len(unique_results)} matched events for term '{term}'."
|
||||
)
|
||||
return results
|
||||
return list(unique_results.values())
|
||||
|
||||
def _find_previous_date_text(self, heading) -> str | None:
|
||||
current = heading.previous_sibling
|
||||
while current is not None:
|
||||
def _find_card_link(self, heading):
|
||||
link = heading.find_parent("a", href=re.compile(r"/events/"))
|
||||
if link is not None:
|
||||
return link
|
||||
|
||||
current = heading
|
||||
for _ in range(5):
|
||||
current = current.parent
|
||||
if current is None:
|
||||
return None
|
||||
link = current.find("a", href=re.compile(r"/events/"))
|
||||
if link is not None and heading in link.find_all("h3"):
|
||||
return link
|
||||
return None
|
||||
|
||||
def _find_card_date_text(self, heading) -> str | None:
|
||||
current = heading
|
||||
for _ in range(6):
|
||||
current = current.previous_element
|
||||
if current is None:
|
||||
return None
|
||||
text = getattr(current, "get_text", lambda *args, **kwargs: str(current))(
|
||||
" ", strip=True
|
||||
)
|
||||
if text and "|" in text:
|
||||
return text
|
||||
current = current.previous_sibling
|
||||
date_text = self._extract_date_text(text)
|
||||
if date_text:
|
||||
return date_text
|
||||
return None
|
||||
|
||||
def _extract_date_text(self, text: str) -> str | None:
|
||||
match = re.search(
|
||||
r"(Montag|Dienstag|Mittwoch|Donnerstag|Freitag|Samstag|Sonntag)\s*\|\s*(\d{2}\.\d{2}\.\d{4})",
|
||||
text,
|
||||
)
|
||||
if match:
|
||||
return match.group(2)
|
||||
|
||||
match = re.search(r"\b(\d{2}\.\d{2}\.\d{4})\b", text)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
def _parse_german_date(self, value: str | None) -> datetime | None:
|
||||
if not value:
|
||||
return None
|
||||
parts = [part.strip() for part in value.split("|")]
|
||||
if len(parts) < 2:
|
||||
return None
|
||||
try:
|
||||
return datetime.strptime(parts[1], "%d.%m.%Y")
|
||||
return datetime.strptime(value, "%d.%m.%Y")
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user