diff --git a/brancheneinstufung.py b/brancheneinstufung.py index 21d9e32a..8fef66b6 100644 --- a/brancheneinstufung.py +++ b/brancheneinstufung.py @@ -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"""