Robuste, lineare Wikipedia-Suche
- REFACTOR: Die komplexe, rekursive `search_company_article`-Funktion in `wikipedia_scraper.py` wurde durch eine einfache, lineare Implementierung ersetzt. - FIX: Der hartnäckige `TypeError` bei der Parameter-Übergabe wurde durch die neue, übersichtlichere Struktur endgültig behoben. - FEATURE: Die Suche prüft nun intelligent eine Liste von Suchbegriffen und validiert jeden potenziellen Treffer, was die Zuverlässigkeit erhöht.
This commit is contained in:
@@ -212,78 +212,57 @@ class WikipediaScraper:
|
||||
|
||||
def search_company_article(self, company_name, website=None, parent_name=None, max_recursion_depth=1):
|
||||
"""
|
||||
Sucht einen passenden Wikipedia-Artikel. Finale Version mit korrekter
|
||||
Parameter-Weitergabe an die innere rekursive Funktion.
|
||||
Sucht einen passenden Wikipedia-Artikel für ein Unternehmen durch eine lineare
|
||||
Überprüfung generierter Suchbegriffe. Diese Methode ist einfacher und robuster
|
||||
als die alte, rekursive Implementierung.
|
||||
"""
|
||||
if not company_name or str(company_name).strip() == "":
|
||||
self.logger.warning("Wikipedia search skipped: No company name provided.")
|
||||
if not company_name:
|
||||
self.logger.warning("Wikipedia-Suche übersprungen: Kein Firmenname angegeben.")
|
||||
return None
|
||||
|
||||
search_terms = self._generate_search_terms(company_name, website)
|
||||
if not search_terms:
|
||||
self.logger.warning(f"Keine Suchbegriffe fuer '{company_name[:100]}...' generiert.")
|
||||
return None
|
||||
self.logger.info(f"Starte Wikipedia-Suche für '{company_name[:50]}...' mit Begriffen: {search_terms}")
|
||||
|
||||
self.logger.info(f"Starte Wikipedia-Suche fuer '{company_name[:100]}...' mit Begriffen: {search_terms}")
|
||||
|
||||
processed_titles = set()
|
||||
original_search_name_norm = normalize_company_name(company_name)
|
||||
|
||||
# Die innere Funktion erbt `parent_name` aus dem Scope der äußeren Funktion.
|
||||
def check_page_recursive(title_to_check, current_depth):
|
||||
effective_max_depth = max_recursion_depth if max_recursion_depth is not None else 2
|
||||
if title_to_check in processed_titles or current_depth > effective_max_depth:
|
||||
return None
|
||||
|
||||
processed_titles.add(title_to_check)
|
||||
self.logger.debug(f" -> Pruefe potenziellen Artikel: '{title_to_check[:100]}...' (Tiefe: {current_depth})")
|
||||
|
||||
normalized_option_title_local = normalize_company_name(title_to_check)
|
||||
title_similarity_to_original = fuzzy_similarity(normalized_option_title_local, original_search_name_norm)
|
||||
|
||||
if current_depth > 0 and title_similarity_to_original < 0.3:
|
||||
self.logger.debug(f" -> Option '{title_to_check[:100]}' hat zu geringe Ähnlichkeit ({title_similarity_to_original:.2f}). Übersprungen.")
|
||||
return None
|
||||
|
||||
page = None
|
||||
try:
|
||||
page = wikipedia.page(title_to_check, auto_suggest=False, preload=False, redirect=True)
|
||||
# KORRIGIERTER AUFRUF: Übergibt jetzt 5 Argumente, wie von _validate_article erwartet.
|
||||
if self._validate_article(page, company_name, website, parent_name):
|
||||
self.logger.info(f" -> Titel '{page.title[:100]}...' erfolgreich validiert!")
|
||||
return page
|
||||
else:
|
||||
return None
|
||||
except wikipedia.exceptions.PageError:
|
||||
self.logger.debug(f" -> Artikel '{title_to_check[:100]}' nicht gefunden (PageError).")
|
||||
return None
|
||||
except wikipedia.exceptions.DisambiguationError as e_disamb:
|
||||
self.logger.info(f" -> Begriffsklaerung '{e_disamb.title}' gefunden (Tiefe {current_depth}). Pruefe Optionen...")
|
||||
if current_depth >= effective_max_depth: return None
|
||||
|
||||
relevant_options = []
|
||||
for option in e_disamb.options:
|
||||
option_lower = option.lower()
|
||||
if not any(ex in option_lower for ex in ["(person)", "(familienname)"]) and len(option) < 80:
|
||||
if fuzzy_similarity(normalize_company_name(option), original_search_name_norm) > 0.3:
|
||||
relevant_options.append(option)
|
||||
|
||||
for option_to_check in relevant_options[:3]:
|
||||
# Der rekursive Aufruf ist korrekt und einfach.
|
||||
validated_page = check_page_recursive(option_to_check, current_depth + 1)
|
||||
if validated_page: return validated_page
|
||||
return None
|
||||
except Exception as e_page:
|
||||
title_for_log = page.title[:100] if page and hasattr(page, 'title') and page.title else title_to_check[:100]
|
||||
self.logger.error(f" -> Unerwarteter Fehler bei Verarbeitung von Seite '{title_for_log}': {e_page}")
|
||||
return None
|
||||
|
||||
# Hauptlogik der Suche
|
||||
for term in search_terms:
|
||||
page_found = check_page_recursive(term, 0)
|
||||
if page_found: return page_found
|
||||
self.logger.debug(f" -> Prüfe Suchbegriff: '{term}'")
|
||||
try:
|
||||
# Nutze die Suchfunktion von Wikipedia, die besser mit uneindeutigen Begriffen umgeht
|
||||
# und oft direkt die richtige Seite vorschlägt.
|
||||
suggested_titles = wikipedia.search(term, results=3)
|
||||
if not suggested_titles:
|
||||
continue
|
||||
|
||||
self.logger.warning(f"Kein passender & validierter Wikipedia-Artikel fuer '{company_name[:100]}...' gefunden.")
|
||||
for title in suggested_titles:
|
||||
self.logger.debug(f" -> Potenzieller Artikel gefunden: '{title}'")
|
||||
try:
|
||||
page = wikipedia.page(title, auto_suggest=False, redirect=True)
|
||||
# Validiere den gefundenen Artikel mit dem vollen Kontext
|
||||
if self._validate_article(page, company_name, website, parent_name):
|
||||
self.logger.info(f" -> ERFOLG: Artikel '{page.title}' wurde für '{company_name}' validiert.")
|
||||
return page
|
||||
else:
|
||||
# Artikel ist nicht relevant, fahre mit dem nächsten Vorschlag fort
|
||||
continue
|
||||
except wikipedia.exceptions.DisambiguationError as e:
|
||||
self.logger.debug(f" -> Begriffsklärungsseite '{title}' gefunden. Prüfe Optionen...")
|
||||
# Prüfe die ersten 3 Optionen der Begriffsklärungsseite
|
||||
for option in e.options[:3]:
|
||||
try:
|
||||
page = wikipedia.page(option, auto_suggest=False, redirect=True)
|
||||
if self._validate_article(page, company_name, website, parent_name):
|
||||
self.logger.info(f" -> ERFOLG: Artikel '{page.title}' aus Begriffsklärung validiert.")
|
||||
return page
|
||||
except Exception:
|
||||
continue # Ignoriere Fehler bei einzelnen Optionen
|
||||
except Exception:
|
||||
# Ignoriere Fehler beim Laden einer einzelnen Seite und mache weiter
|
||||
continue
|
||||
|
||||
except Exception as e_search:
|
||||
self.logger.error(f" -> Unerwarteter Fehler bei der Suche mit Begriff '{term}': {e}")
|
||||
continue # Mache mit dem nächsten Suchbegriff weiter
|
||||
|
||||
self.logger.warning(f"Kein passender & validierter Wikipedia-Artikel für '{company_name[:50]}...' gefunden.")
|
||||
return None
|
||||
|
||||
def _extract_first_paragraph_from_soup(self, soup):
|
||||
|
||||
Reference in New Issue
Block a user