infobox bugfix

Erweiterte Infobox-Erkennung:

Unterstützt jetzt zusätzliche Klassen wie firma und unternehmensdaten

Berücksichtigt div-Elemente neben Tabellenzeilen

Verbesserte Schlüsselwörter:

50% mehr Keywords für Branchen- und Umsatzfelder

Berücksichtigt typisch deutsche Formulierungen

Flexible Wertextraktion:

Verarbeitet Listen (<li>-Elemente)

Ignoriert Navigationsboxen (navbox-Klasse)

Sucht in verschiedenen HTML-Elementen (div, td, th)

Robuste Umsatzanalyse:

Erkennt verschiedene Schreibweisen:

"123,45 Mio. €"

"1.234,56 Millionen Euro"

"5,6 Mrd. USD"

Führt automatische Umrechnung durch:

1 Milliarde → 1000 Millionen

Standardisiert die Ausgabe auf "X.X Mio €"

Erweiterte Debug-Informationen:

Protokolliert fehlgeschlagene Suchvorgänge

Zeigt erkannte Werte im Rohformat an
This commit is contained in:
2025-03-31 15:11:39 +00:00
parent 05185396c7
commit f665612146

View File

@@ -179,40 +179,83 @@ class WikipediaScraper:
debug_print(f"Extraktionsfehler: {str(e)}")
return {'branche': 'k.A.', 'umsatz': 'k.A.', 'url': page_url}
def _extract_infobox_value(self, soup, target):
"""Robuste Infobox-Analyse"""
infobox = soup.find('table', class_=lambda c: c and any(
kw in c.lower() for kw in ['infobox', 'vcard', 'unternehmen']
))
if not infobox:
return "k.A."
keywords = {
'branche': ['branche', 'industrie', 'tätigkeitsfeld', 'geschäftsfeld'],
'umsatz': ['umsatz', 'jahresumsatz', 'konzernumsatz', 'erlöse']
}[target]
for row in infobox.find_all('tr'):
header = row.find('th')
if header:
header_text = clean_text(header.get_text()).lower()
if any(kw in header_text for kw in keywords):
value = row.find('td')
if value:
raw_value = clean_text(value.get_text())
# Umsatzbereinigung
if target == 'umsatz':
match = re.search(
r'(\d{1,3}(?:[.,]\d{3})*)\s*(?:Mio\.?|Millionen|Mrd\.?|Milliarden)?',
raw_value
)
if match:
return match.group(1).replace('.', '').replace(',', '.')
return raw_value
def _extract_infobox_value(self, soup, target):
"""Verbesserte Infobox-Extraktion mit erweiterten Mustern"""
# Erweiterte Infobox-Erkennung
infobox = soup.find('table', class_=lambda c: c and any(
kw in c.lower() for kw in [
'infobox', 'vcard', 'unternehmen',
'firma', 'unternehmensdaten', 'firmendaten'
]
))
if not infobox:
debug_print("Keine Infobox gefunden")
return "k.A."
# Erweiterte Keywords für Deutsch
keywords = {
'branche': [
'branche', 'industrie', 'tätigkeitsfeld',
'geschäftsfeld', 'sektor', 'branchen',
'wirtschaftszweig', 'tätigkeitsbereich',
'produkte', 'leistungen'
],
'umsatz': [
'umsatz', 'jahresumsatz', 'konzernumsatz',
'gesamtumsatz', 'umsatzerlöse', 'erlöse',
'umsatzentwicklung', 'ergebnis',
'umsatz in millionen', 'jahresergebnis'
]
}[target]
# Durchsuche alle möglichen Zellenstrukturen
for row in infobox.find_all(['tr', 'div']):
header = row.find(['th', 'td', 'div'], class_=lambda c: c != 'navbox')
if header:
header_text = clean_text(header.get_text()).lower()
if any(kw in header_text for kw in keywords):
value = ""
# Finde den Wert in verschiedenen möglichen Positionen
value_cell = header.find_next(['td', 'li', 'div'])
if value_cell:
# Verarbeite Listen und mehrzeilige Inhalte
list_items = value_cell.find_all('li')
if list_items:
value = ', '.join(clean_text(li.get_text()) for li in list_items)
else:
value = clean_text(value_cell.get_text())
# Spezielle Verarbeitung für Umsatz
if target == 'umsatz':
# Erweitertes Regex für verschiedene Formate
match = re.search(
r'''
([\d.,]+)\s* # Basisnummer
(?:Mio\.?|Millionen|Mrd\.?|Milliarden)?\s* # Einheit
(?:€|Euro|EUR|USD|\$)? # Währung
(?:\s*\(.*?\))? # Eventuelle Klammerzusätze
''',
value,
re.VERBOSE | re.IGNORECASE
)
if match:
# Normalisierung der Zahlen
clean_value = match.group(1)
clean_value = clean_value.replace('.', '').replace(',', '.')
# Millionen Umrechnung
if 'mrd' in value.lower() or 'milliarden' in value.lower():
clean_value = str(float(clean_value) * 1000)
return f"{float(clean_value):.1f} Mio €"
else:
return value.strip()
return value.strip() if value else "k.A."
debug_print(f"{target} nicht in Infobox gefunden")
return "k.A."
# ==================== DATA PROCESSOR ====================
class DataProcessor:
"""Steuerung des Gesamtprozesses"""