bugfix
This commit is contained in:
@@ -3652,7 +3652,7 @@ class WikipediaScraper:
|
||||
return result
|
||||
|
||||
@retry_on_failure
|
||||
def search_company_article(self, company_name, website=None, max_recursion_depth=2): # max_recursion_depth hinzugefügt
|
||||
def search_company_article(self, company_name, website=None, max_recursion_depth=1): # max_recursion_depth hinzugefügt
|
||||
"""
|
||||
Sucht einen passenden Wikipedia-Artikel fuer das Unternehmen und gibt das
|
||||
wikipedia.WikipediaPage Objekt zurueck, wenn ein relevanter und validierter
|
||||
@@ -3671,82 +3671,121 @@ class WikipediaScraper:
|
||||
f"Starte Wikipedia-Suche fuer '{company_name[:100]}...' "
|
||||
f"(Website: {website[:100]}...) mit Begriffen: {search_terms}"
|
||||
)
|
||||
processed_titles = set() # Verhindert Endlosschleifen bei zirkulären Redirects/Disambiguations
|
||||
processed_titles = set()
|
||||
original_search_name_norm = normalize_company_name(company_name) # Einmal normalisieren
|
||||
|
||||
# Innere Hilfsfunktion mit Rekursionstiefe
|
||||
def check_page_recursive(title_to_check, current_depth):
|
||||
if title_to_check in processed_titles or current_depth > max_recursion_depth:
|
||||
if title_to_check in processed_titles:
|
||||
self.logger.debug(f" -> Titel '{title_to_check[:100]}...' bereits verarbeitet oder Rekursionstiefe überschritten.")
|
||||
page_object_to_return = None # Explizit initialisieren
|
||||
|
||||
if title_to_check in processed_titles:
|
||||
self.logger.debug(f" -> Titel '{title_to_check[:100]}...' bereits verarbeitet. Übersprungen.")
|
||||
return None
|
||||
if current_depth > max_recursion_depth:
|
||||
self.logger.debug(f" -> Maximale Rekursionstiefe ({max_recursion_depth}) für '{title_to_check[:100]}...' erreicht. Stoppe.")
|
||||
return None
|
||||
|
||||
processed_titles.add(title_to_check)
|
||||
|
||||
self.logger.debug(f" -> Pruefe potenziellen Artikel: '{title_to_check[:100]}...' (Tiefe: {current_depth})")
|
||||
|
||||
try:
|
||||
page = wikipedia.page(title_to_check, auto_suggest=False, preload=True)
|
||||
# preload=False, um nicht sofort alles zu laden
|
||||
page = wikipedia.page(title_to_check, auto_suggest=False, preload=False, redirect=True)
|
||||
|
||||
# Validierung durchführen
|
||||
if self._validate_article(page, company_name, website): # company_name ist der ursprüngliche Suchname
|
||||
self.logger.info(f" -> Titel '{page.title[:100]}...' erfolgreich validiert!")
|
||||
return page
|
||||
page_object_to_return = page # Potenziell guter Artikel
|
||||
else:
|
||||
self.logger.debug(f" -> Titel '{title_to_check[:100]}...' nicht validiert.")
|
||||
return None
|
||||
self.logger.debug(f" -> Titel '{page.title[:100]}...' nicht validiert.")
|
||||
page_object_to_return = None # Nicht validiert
|
||||
|
||||
except wikipedia.exceptions.DisambiguationError as e_disamb:
|
||||
self.logger.info(
|
||||
f" -> Begriffsklaerung '{e_disamb.title}' gefunden für '{title_to_check[:100]}...' (Tiefe {current_depth}). "
|
||||
f"Pruefe Optionen (max 3 nach Filter): {str(e_disamb.options[:10])[:200]}..." # Zeige nur die ersten paar Optionen
|
||||
)
|
||||
if current_depth >= max_recursion_depth:
|
||||
self.logger.warning(f" -> Max Rekursionstiefe für Begriffsklärung '{e_disamb.title}' erreicht. Stoppe weitere Auflösung.")
|
||||
return None # Wichtig: None zurückgeben
|
||||
|
||||
relevant_options = []
|
||||
for option_title in e_disamb.options:
|
||||
option_lower = option_title.lower()
|
||||
# Verbesserte Filterung
|
||||
if not any(ex in option_lower for ex in [
|
||||
"(person)", "(familienname)", "(vorname)", "(künstlername)", "liste von",
|
||||
"(ort)", "(geographie)", "(stadt)", "(gemeinde)", "(landkreis)", "river", "bayou",
|
||||
"liste ", "liste)", "(album)", "(film)", "(lied)", "(manga)", " (Begriffsklärung)",
|
||||
"(einheit)", "(maßeinheit)", " (Begriffsklärung)", " (Begriffsklärungshinweis)", "begriffsklärung",
|
||||
" (surname)", " (given name)", " (band)", " (musician)", " (album)", " (song)",
|
||||
" (film)", " (tv series)", " (character)", " (comics)", " (disambiguation)" # Englische Varianten
|
||||
]) and len(option_title) < 80: # Kürzere Titel bevorzugen
|
||||
# Zusätzlicher Check: Ähnlichkeit der Option zum *Original* Suchbegriff
|
||||
normalized_option = normalize_company_name(option_title)
|
||||
if fuzzy_similarity(normalized_option, original_search_name_norm) > 0.3: # Mindestähnlichkeit
|
||||
relevant_options.append(option_title)
|
||||
|
||||
self.logger.debug(f" -> {len(relevant_options)} potenziell relevante Optionen für '{e_disamb.title}' nach Filterung: {str(relevant_options[:5])[:200]}...")
|
||||
|
||||
# Nur die Top N relevantesten Optionen prüfen (z.B. die ersten 3)
|
||||
for i, option_to_check_further in enumerate(relevant_options[:3]): # << HIER LIMITIEREN
|
||||
validated_page_from_option = check_page_recursive(option_to_check_further, current_depth + 1)
|
||||
if validated_page_from_option:
|
||||
self.logger.info(f" -> Option '{option_to_check_further[:100]}...' aus Begriffsklaerung erfolgreich validiert!")
|
||||
return validated_page_from_option # Gib die erste valide Seite zurück
|
||||
|
||||
self.logger.debug(f" -> Keine passende/validierte Unternehmens-Option in Begriffsklaerung '{e_disamb.title}' gefunden.")
|
||||
return None # Keine valide Option gefunden
|
||||
|
||||
except wikipedia.exceptions.PageError:
|
||||
self.logger.debug(f" -> Seite '{title_to_check[:100]}...' nicht gefunden (PageError).")
|
||||
return None
|
||||
except wikipedia.exceptions.DisambiguationError as e_inner:
|
||||
self.logger.info(
|
||||
f" -> Begriffsklaerung '{title_to_check[:100]}...' gefunden (Tiefe {current_depth}). "
|
||||
f"Pruefe Optionen: {str(e_inner.options)[:100]}..."
|
||||
)
|
||||
if current_depth >= max_recursion_depth:
|
||||
self.logger.warning(f" -> Maximale Rekursionstiefe ({max_recursion_depth}) für Begriffsklärung '{title_to_check[:100]}...' erreicht. Stoppe weitere Auflösung.")
|
||||
return None
|
||||
|
||||
# Filtere und priorisiere Optionen
|
||||
# Man könnte hier noch intelligenter filtern, z.B. Optionen bevorzugen, die "(Unternehmen)" enthalten
|
||||
valid_options = []
|
||||
for option in e_inner.options:
|
||||
option_lower = option.lower()
|
||||
# Erweiterte Negativ-Filterung
|
||||
if not any(
|
||||
ex in option_lower
|
||||
for ex in [
|
||||
"(person)", "(familienname)", "(vorname)", "(künstlername)",
|
||||
"(ort)", "(geographie)", "(stadt)", "(gemeinde)", "(landkreis)",
|
||||
"liste ", "liste)", "(album)", "(film)", "(lied)", "(manga)",
|
||||
"(einheit)", "(maßeinheit)", "(begriffsklärung)", "Begriffsklärung)" # Begriffsklärungen explizit ausschließen für direkte Rekursion
|
||||
]
|
||||
) and len(option) < 100 : # Vermeide extrem lange Options-Strings
|
||||
valid_options.append(option)
|
||||
|
||||
self.logger.debug(f" -> {len(valid_options)} potenziell relevante Optionen für '{title_to_check[:100]}...' nach Filterung: {str(valid_options)[:200]}...")
|
||||
|
||||
for option in valid_options:
|
||||
# Rekursiver Aufruf mit erhöhter Tiefe
|
||||
validated_option_page = check_page_recursive(option, current_depth + 1)
|
||||
if validated_option_page:
|
||||
self.logger.info(
|
||||
f" -> Option '{option[:100]}...' aus Begriffsklaerung erfolgreich validiert!"
|
||||
)
|
||||
return validated_option_page
|
||||
|
||||
self.logger.debug(
|
||||
f" -> Keine passende/validierte Unternehmens-Option in Begriffsklaerung '{title_to_check[:100]}...' gefunden."
|
||||
)
|
||||
return None # Wichtig: Gibt None zurück, wenn keine der Optionen erfolgreich war
|
||||
except (requests.exceptions.RequestException, wikipedia.exceptions.WikipediaException) as e_req:
|
||||
self.logger.warning(
|
||||
f" -> Netzwerk/API-Fehler beim Laden/Validieren von '{title_to_check[:100]}...': "
|
||||
f"{type(e_req).__name__} - {e_req}. Ueberspringe diesen Titel."
|
||||
)
|
||||
self.logger.warning(f" -> Netzwerk/API-Fehler bei Verarbeitung von '{title_to_check[:100]}...': {e_req}")
|
||||
return None
|
||||
except Exception as e_page:
|
||||
self.logger.error(
|
||||
f" -> Unerwarteter Fehler bei Verarbeitung von Titel '{title_to_check[:100]}...': "
|
||||
f"{type(e_page).__name__} - {e_page}"
|
||||
)
|
||||
# Aggressiveres Abfangen von Fehlern beim Zugriff auf page-Objekt
|
||||
self.logger.error(f" -> Unerwarteter Fehler bei Verarbeitung von Seite '{title_to_check[:100]}...': {type(e_page).__name__} - {e_page}")
|
||||
self.logger.debug(traceback.format_exc())
|
||||
return None
|
||||
|
||||
return page_object_to_return # Gibt validierte Seite oder None zurück
|
||||
|
||||
# --- Hauptlogik von search_company_article ---
|
||||
# Direkter Match mit dem ursprünglichen Firmennamen
|
||||
self.logger.debug(f" -> Versuche direkten Match fuer '{company_name[:100]}...' mit check_page_recursive...")
|
||||
page_found = check_page_recursive(company_name, original_search_name_norm, current_depth=0)
|
||||
if page_found:
|
||||
return page_found
|
||||
|
||||
# Suche mit generierten Begriffen
|
||||
self.logger.debug(f" -> Kein direkter Treffer/validiert. Starte Suche mit generierten Begriffen via check_page_recursive: {search_terms}")
|
||||
for term in search_terms:
|
||||
if term == company_name: continue # Bereits oben geprüft
|
||||
self.logger.debug(f" -> Versuche Suchbegriff: '{term[:100]}...' mit check_page_recursive...")
|
||||
page_found = check_page_recursive(term, original_search_name_norm, current_depth=0) # Starte Rekursion für den Term
|
||||
if page_found:
|
||||
return page_found
|
||||
|
||||
# Die wikipedia.search() wird hier nicht mehr primär genutzt,
|
||||
# da check_page_recursive schon die wikipedia.page()-Suche macht.
|
||||
# Falls check_page_recursive(term) nichts findet, könnten wir hier optional
|
||||
# noch wikipedia.search() als Fallback nutzen, aber mit Vorsicht.
|
||||
# Fürs Erste lassen wir es weg, um die API-Calls zu reduzieren.
|
||||
#
|
||||
# try:
|
||||
# search_results = wikipedia.search(term, results=getattr(Config, 'WIKIPEDIA_SEARCH_RESULTS', 2)) # Weniger Ergebnisse
|
||||
# if search_results:
|
||||
# self.logger.debug(f" -> Fallback wikipedia.search für '{term[:100]}...' ergab: {search_results}")
|
||||
# for title in search_results:
|
||||
# page_found = check_page_recursive(title, original_search_name_norm, current_depth=0)
|
||||
# if page_found:
|
||||
# return page_found
|
||||
# except Exception as e_search:
|
||||
# self.logger.error(f"Fehler waehrend Fallback wikipedia.search() fuer '{term[:100]}...': {e_search}")
|
||||
|
||||
self.logger.warning(f"Kein passender & validierter Wikipedia-Artikel fuer '{company_name[:100]}...' gefunden nach allen Versuchen.")
|
||||
return None
|
||||
|
||||
# Direkter Match mit dem ursprünglichen Firmennamen
|
||||
self.logger.debug(f" -> Versuche direkten Match fuer '{company_name[:100]}...'...")
|
||||
|
||||
Reference in New Issue
Block a user