bugfix
This commit is contained in:
@@ -3638,107 +3638,139 @@ class WikipediaScraper:
|
||||
return result
|
||||
|
||||
@retry_on_failure
|
||||
def search_company_article(self, company_name, website=None):
|
||||
def search_company_article(self, company_name, website=None, max_recursion_depth=2): # 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
|
||||
Artikel gefunden wird. Behandelt explizit Begriffsklaerungsseiten.
|
||||
"""
|
||||
if not company_name or str(company_name).strip() == "":
|
||||
self.logger.warning("Wikipedia search skipped: No company name provided.") # <<< GEÄNDERT
|
||||
self.logger.warning("Wikipedia search skipped: No company name provided.")
|
||||
raise ValueError("Kein Firmenname fuer Wikipedia Suche angegeben.")
|
||||
|
||||
search_terms = self._generate_search_terms(company_name, website)
|
||||
if not search_terms:
|
||||
self.logger.warning(f"Keine Suchbegriffe fuer '{company_name[:100]}...' generiert.") # <<< GEÄNDERT
|
||||
self.logger.warning(f"Keine Suchbegriffe fuer '{company_name[:100]}...' generiert.")
|
||||
return None
|
||||
|
||||
self.logger.info( # <<< GEÄNDERT
|
||||
self.logger.info(
|
||||
f"Starte Wikipedia-Suche fuer '{company_name[:100]}...' "
|
||||
f"(Website: {website[:100]}...) mit Begriffen: {search_terms}"
|
||||
)
|
||||
processed_titles = set()
|
||||
processed_titles = set() # Verhindert Endlosschleifen bei zirkulären Redirects/Disambiguations
|
||||
|
||||
def check_page(title_to_check):
|
||||
if title_to_check in processed_titles:
|
||||
# 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.")
|
||||
return None
|
||||
processed_titles.add(title_to_check)
|
||||
self.logger.debug(f" -> Pruefe potenziellen Artikel: '{title_to_check[:100]}...'") # <<< GEÄNDERT
|
||||
|
||||
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)
|
||||
if self._validate_article(page, company_name, website):
|
||||
self.logger.info(f" -> Titel '{page.title[:100]}...' erfolgreich validiert!") # <<< GEÄNDERT
|
||||
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
|
||||
else:
|
||||
self.logger.debug(f" -> Titel '{title_to_check[:100]}...' nicht validiert.") # <<< GEÄNDERT
|
||||
self.logger.debug(f" -> Titel '{title_to_check[:100]}...' nicht validiert.")
|
||||
return None
|
||||
except wikipedia.exceptions.PageError:
|
||||
self.logger.debug(f" -> Seite '{title_to_check[:100]}...' nicht gefunden (PageError).") # <<< GEÄNDERT
|
||||
self.logger.debug(f" -> Seite '{title_to_check[:100]}...' nicht gefunden (PageError).")
|
||||
return None
|
||||
except wikipedia.exceptions.DisambiguationError as e_inner:
|
||||
self.logger.info( # <<< GEÄNDERT
|
||||
f" -> Begriffsklaerung '{title_to_check[:100]}...' gefunden. "
|
||||
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()
|
||||
if any(
|
||||
# Erweiterte Negativ-Filterung
|
||||
if not any(
|
||||
ex in option_lower
|
||||
for ex in ["(person)", "(ort)", "(geographie)", "liste ", "liste)"]
|
||||
):
|
||||
continue
|
||||
validated_option_page = check_page(option)
|
||||
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( # <<< GEÄNDERT
|
||||
self.logger.info(
|
||||
f" -> Option '{option[:100]}...' aus Begriffsklaerung erfolgreich validiert!"
|
||||
)
|
||||
return validated_option_page
|
||||
self.logger.debug( # <<< GEÄNDERT
|
||||
|
||||
self.logger.debug(
|
||||
f" -> Keine passende/validierte Unternehmens-Option in Begriffsklaerung '{title_to_check[:100]}...' gefunden."
|
||||
)
|
||||
return None
|
||||
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( # <<< GEÄNDERT
|
||||
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."
|
||||
)
|
||||
return None
|
||||
except Exception as e_page:
|
||||
self.logger.error( # <<< GEÄNDERT
|
||||
self.logger.error(
|
||||
f" -> Unerwarteter Fehler bei Verarbeitung von Titel '{title_to_check[:100]}...': "
|
||||
f"{type(e_page).__name__} - {e_page}"
|
||||
)
|
||||
self.logger.debug(traceback.format_exc()) # <<< GEÄNDERT
|
||||
self.logger.debug(traceback.format_exc())
|
||||
return None
|
||||
|
||||
self.logger.debug(f" -> Versuche direkten Match fuer '{company_name[:100]}...'...") # <<< GEÄNDERT
|
||||
validated_page = check_page(company_name)
|
||||
# Direkter Match mit dem ursprünglichen Firmennamen
|
||||
self.logger.debug(f" -> Versuche direkten Match fuer '{company_name[:100]}...'...")
|
||||
validated_page = check_page_recursive(company_name, current_depth=0) # Starte mit Tiefe 0
|
||||
if validated_page:
|
||||
return validated_page
|
||||
|
||||
self.logger.debug( # <<< GEÄNDERT
|
||||
# Suche mit generierten Begriffen
|
||||
self.logger.debug(
|
||||
f" -> Kein direkter Treffer/validiert. Starte Suche mit generierten Begriffen: {search_terms}"
|
||||
)
|
||||
for term in search_terms:
|
||||
if term == company_name: continue # Bereits oben geprüft
|
||||
|
||||
try:
|
||||
self.logger.debug(f" -> Suche mit Begriff: '{term[:100]}...'...") # <<< GEÄNDERT
|
||||
search_results = wikipedia.search(term, results=getattr(Config, 'WIKIPEDIA_SEARCH_RESULTS', 5))
|
||||
self.logger.debug(f" -> Suchergebnisse fuer '{term[:100]}...': {search_results}") # <<< GEÄNDERT
|
||||
self.logger.debug(f" -> Suche mit Begriff: '{term[:100]}...'...")
|
||||
search_results = wikipedia.search(term, results=getattr(Config, 'WIKIPEDIA_SEARCH_RESULTS', 3)) # Weniger Ergebnisse pro Term
|
||||
self.logger.debug(f" -> Suchergebnisse fuer '{term[:100]}...': {search_results}")
|
||||
if not search_results:
|
||||
self.logger.debug(f" -> Keine Suchergebnisse fuer '{term[:100]}...'.") # <<< GEÄNDERT
|
||||
self.logger.debug(f" -> Keine Suchergebnisse fuer '{term[:100]}...'.")
|
||||
continue
|
||||
for title in search_results:
|
||||
validated_page = check_page(title)
|
||||
validated_page = check_page_recursive(title, current_depth=0) # Starte mit Tiefe 0 für jeden neuen Suchtreffer
|
||||
if validated_page:
|
||||
return validated_page
|
||||
except Exception as e_search:
|
||||
self.logger.error( # <<< GEÄNDERT
|
||||
f"Fehler waehrend Wikipedia-Suche fuer '{term[:100]}...': "
|
||||
# Fehler von wikipedia.search() selbst, nicht von check_page_recursive
|
||||
self.logger.error(
|
||||
f"Fehler waehrend Wikipedia-Suche (wikipedia.search) fuer '{term[:100]}...': "
|
||||
f"{type(e_search).__name__} - {e_search}"
|
||||
)
|
||||
raise e_search
|
||||
# Hier nicht direkt 'raise e_search', da der Retry-Decorator auf search_company_article liegt.
|
||||
# Wenn dies ein wiederholbarer Fehler der wikipedia-Bibliothek ist, sollte der Decorator greifen.
|
||||
# Für den Moment loggen wir und machen mit dem nächsten Suchbegriff weiter.
|
||||
# Bei einem persistenten API-Problem wird der äußere Decorator nach mehreren Versuchen abbrechen.
|
||||
|
||||
self.logger.warning( # <<< GEÄNDERT
|
||||
|
||||
self.logger.warning(
|
||||
f"Kein passender & validierter Wikipedia-Artikel fuer '{company_name[:100]}...' gefunden nach Pruefung aller Begriffe und Optionen."
|
||||
)
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user