From b123eee5a81b52ec840ea10fa902ec3d8f08fe0c Mon Sep 17 00:00:00 2001 From: Ratatoskr Date: Sat, 4 Apr 2026 15:26:08 +0200 Subject: [PATCH] string an ki effektiver/kleiner gemacht --- crawler.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/crawler.py b/crawler.py index 0e8110d..ba8d51e 100644 --- a/crawler.py +++ b/crawler.py @@ -57,7 +57,27 @@ def setup_db(): conn.commit() 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): + if not ist_sinnvoller_text(text): + logger.debug(f"Überspringe Müll-Text: {url}") + return + conn = sqlite3.connect(DB_PATH, timeout=20) cursor = conn.cursor() cursor.execute("SELECT 1 FROM artikel WHERE artikel_url = ?", (url,)) @@ -91,12 +111,23 @@ def extrahiere_links(soup, basis_url): def hole_artikel_text(url): try: antwort = scraper.get(url, timeout=10) - unter_soup = BeautifulSoup(antwort.text, "html.parser") - bereich = unter_soup.find("main") or unter_soup.find("article") or unter_soup.body - return bereich.get_text(separator=" ", strip=True) + 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 + + text = bereich.get_text(separator=" ", strip=True) + return text[:12000] except Exception as e: logger.error(f"Fehler bei {url}: {e}") - return f"Fehler: {e}" + return None def finde_link_fuer_text(text_snippet, soup, basis_url): schnipsel = text_snippet.strip().lower() @@ -115,30 +146,42 @@ def verarbeite_website(url): antwort = scraper.get(url, timeout=15) if antwort.status_code != 200: return soup = BeautifulSoup(antwort.text, "html.parser") - hauptbereich = soup.find("main") or soup.find("article") or soup.body or soup + + # Müll entfernen + 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}") + return + neuer_text = hauptbereich.get_text(separator=" ", strip=True) cursor.execute("SELECT inhalt FROM seiten_stand WHERE url = ?", (url,)) zeile = cursor.fetchone() alter_text = zeile[0] if zeile else "" - aktuelle_links = extrahiere_links(hauptbereich, url) + aktuelle_links = extrahiere_links(soup, url) for link in aktuelle_links: cursor.execute("SELECT 1 FROM artikel WHERE artikel_url = ?", (link,)) if cursor.fetchone() is None: logger.info(f"Neu: {link}") artikel_inhalt = hole_artikel_text(link) - queue_article(link, artikel_inhalt, url) + if artikel_inhalt: + queue_article(link, artikel_inhalt, url) if alter_text != neuer_text: diff = [z[2:] for z in difflib.ndiff(alter_text.splitlines(), neuer_text.splitlines()) if z.startswith("+ ") and len(z[2:].strip()) > 30] for line in diff: - passender_link = finde_link_fuer_text(line[:40], hauptbereich, url) + passender_link = finde_link_fuer_text(line[:40], soup, url) target_url = passender_link if passender_link else url cursor.execute("SELECT 1 FROM artikel WHERE artikel_url = ?", (target_url,)) if cursor.fetchone() is None: logger.info(f"Änderung: {target_url}") text_zu_analysieren = hole_artikel_text(passender_link) if passender_link else line - queue_article(target_url, text_zu_analysieren, url) + if text_zu_analysieren: + queue_article(target_url, text_zu_analysieren, url) cursor.execute("INSERT OR REPLACE INTO seiten_stand (url, inhalt, zeit) VALUES (?, ?, ?)", (url, neuer_text, str(datetime.now()))) conn.commit()