From d4f76692db458235c1faf914284766eae9baacc0 Mon Sep 17 00:00:00 2001 From: Ratatoskr Date: Sat, 4 Apr 2026 15:43:13 +0200 Subject: [PATCH] =?UTF-8?q?Syntaxfehler=20in=20crawler.py=20behoben=20und?= =?UTF-8?q?=20Admin-Benachrichtigungen=20f=C3=BCr=20Website-Fehler=20imple?= =?UTF-8?q?mentiert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crawler.py | 49 +++++++++++++++---------------------------------- 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/crawler.py b/crawler.py index 2e9123b..b4d3a28 100644 --- a/crawler.py +++ b/crawler.py @@ -5,6 +5,7 @@ import difflib import sys import subprocess import logging +import requests from bs4 import BeautifulSoup from urllib.parse import urljoin, urlparse from datetime import datetime @@ -34,6 +35,18 @@ scraper = cloudscraper.create_scraper( # --- DATENBANK SETUP --- DB_PATH = os.path.join(BASE_DIR, "polit_scraper.db") +def sende_admin(titel, nachricht): + admin_url = f"{os.getenv('NTFY_BASE')}/polit-scraper-admin" + try: + requests.post( + admin_url, + data=nachricht.encode("utf-8"), + headers={"Title": titel.encode("utf-8"), "Priority": "4"}, + auth=(os.getenv("ADMIN_USER"), os.getenv("ADMIN_PW")), + timeout=5 + ) + except: pass + def setup_db(): conn = sqlite3.connect(DB_PATH, timeout=20) cursor = conn.cursor() @@ -58,19 +71,13 @@ def setup_db(): conn.close() def ist_sinnvoller_text(text): - # Ignoriere Texte, die sehr kurz sind (wahrscheinlich Navigations-Links) if len(text.strip()) < 300: return False - - # Prüfe auf zu viele generische Wörter, die auf Navigations-Seiten hindeuten nav_keywords = ["startseite", "lokales", "aktuelles", "veranstaltungen", "kontakt", "impressum", "baustelle", "meldungen"] text_lower = text.lower() - match_count = sum(text_lower.count(k) for k in nav_keywords) - # Wenn mehr als 5 Navigations-Begriffe vorkommen, ist es vermutlich eine Nav-Seite if match_count > 5: return False - return True def queue_article(url, text, source_url): @@ -112,17 +119,10 @@ def hole_artikel_text(url): try: antwort = scraper.get(url, timeout=10) soup = BeautifulSoup(antwort.text, "html.parser") - - # Müll entfernen for element in soup(["header", "footer", "nav", "script", "style", "aside"]): element.decompose() - - # Gezielter suchen bereich = soup.find("main") or soup.find("article") or soup.find("div", class_="content") - - if not bereich: - return None - + if not bereich: return None text = bereich.get_text(separator=" ", strip=True) return text[:12000] except Exception as e: @@ -143,35 +143,16 @@ def verarbeite_website(url): try: conn = sqlite3.connect(DB_PATH, timeout=20) cursor = conn.cursor() -import requests -from urllib.parse import urljoin, urlparse - -# ... -def sende_admin(titel, nachricht): - admin_url = f"{os.getenv('NTFY_BASE')}/polit-scraper-admin" - try: - requests.post( - admin_url, - data=nachricht.encode("utf-8"), - headers={"Title": titel.encode("utf-8"), "Priority": "4"}, - auth=(os.getenv("ADMIN_USER"), os.getenv("ADMIN_PW")), - timeout=5 - ) - except: pass - -# ... in verarbeite_website ... antwort = scraper.get(url, timeout=15) if antwort.status_code != 200: logger.error(f"Website Fehler: {url} Status {antwort.status_code}") sende_admin("Crawler Fehler", f"URL {url} lieferte Status {antwort.status_code}.") return - soup = BeautifulSoup(antwort.text, "html.parser") - # Müll entfernen + soup = BeautifulSoup(antwort.text, "html.parser") for element in soup(["header", "footer", "nav", "script", "style", "aside"]): element.decompose() - # Gezielter suchen hauptbereich = soup.find("main") or soup.find("article") or soup.find("div", class_="content") if not hauptbereich: logger.debug(f"Überspringe Seite ohne Inhalts-Struktur: {url}")