diff --git a/brancheneinstufung.py b/brancheneinstufung.py index ed9728f6..ffa80af1 100644 --- a/brancheneinstufung.py +++ b/brancheneinstufung.py @@ -3491,62 +3491,184 @@ class WikipediaScraper: sitz_land_val = "k.A." if raw_sitz_string and raw_sitz_string.lower() != "k.a.": - # Versuche Stadt und Land zu trennen (heuristisch) - # Annahme 1: "Stadt (Land)" oder "Stadt, Land" - # Annahme 2: Bekannte Länder am Ende - # Dies ist eine einfache Heuristik und kann verfeinert werden. + temp_sitz = raw_sitz_string.strip() # Am Anfang strippen - temp_sitz = raw_sitz_string - - # Länder, nach denen wir suchen könnten (erweiterbar) - known_countries = { - "deutschland": "Deutschland", "germany": "Deutschland", "de": "Deutschland", - "österreich": "Österreich", "austria": "Österreich", "at": "Österreich", - "schweiz": "Schweiz", "switzerland": "Schweiz", "ch": "Schweiz", - "usa": "USA", "vereinigte staaten": "USA", - "frankreich": "Frankreich", "france": "Frankreich", "fr": "Frankreich", - "niederlande": "Niederlande", "netherlands": "Niederlande", "nl": "Niederlande", - "belgien": "Belgien", "belgium": "Belgien", "be": "Belgien", + # Erweiterte Ländererkennung (Beispiele, muss ausgebaut werden) + # Key: Kleingeschriebene Variante, Value: Standardisierter Ländername + known_countries_detailed = { + # Deutschland + "deutschland": "Deutschland", "germany": "Deutschland", "de": "Deutschland", "brd": "Deutschland", + "bundesrepublik deutschland": "Deutschland", "d-": "Deutschland", # Für "D-PLZ" + # Österreich + "österreich": "Österreich", "austria": "Österreich", "at": "Österreich", "a-": "Österreich", + # Schweiz + "schweiz": "Schweiz", "switzerland": "Schweiz", "ch": "Schweiz", "suisse": "Schweiz", + "svizzera": "Schweiz", "ch-": "Schweiz", "confœderatio helvetica": "Schweiz", + # USA + "usa": "USA", "u.s.": "USA", "u.s.a.": "USA", "united states": "USA", + "vereinigte staaten": "USA", "vereinigte staaten von amerika": "USA", + # Vereinigtes Königreich + "vereinigtes königreich": "Vereinigtes Königreich", "united kingdom": "Vereinigtes Königreich", + "uk": "Vereinigtes Königreich", "gb": "Vereinigtes Königreich", "great britain": "Vereinigtes Königreich", + "england": "Vereinigtes Königreich", "schottland": "Vereinigtes Königreich", # Wenn spezifisch genannt + "wales": "Vereinigtes Königreich", "nordirland": "Vereinigtes Königreich", + # Frankreich + "frankreich": "Frankreich", "france": "Frankreich", "fr": "Frankreich", "f-": "Frankreich", + # Niederlande + "niederlande": "Niederlande", "netherlands": "Niederlande", "nl": "Niederlande", "holland": "Niederlande", + # Belgien + "belgien": "Belgien", "belgium": "Belgien", "be": "Belgien", "belgique": "Belgien", "belgië": "Belgien", + # Luxemburg "luxemburg": "Luxemburg", "luxembourg": "Luxemburg", "lu": "Luxemburg", - "italien": "Italien", "italy": "Italien", "it": "Italien", - "spanien": "Spanien", "spain": "Spanien", "es": "Spanien", + # Italien + "italien": "Italien", "italy": "Italien", "it": "Italien", "i-": "Italien", + # Spanien + "spanien": "Spanien", "spain": "Spanien", "es": "Spanien", "españa": "Spanien", + # Polen "polen": "Polen", "poland": "Polen", "pl": "Polen", - "vereinigtes königreich": "Vereinigtes Königreich", "united kingdom": "Vereinigtes Königreich", "uk": "Vereinigtes Königreich", "gb": "Vereinigtes Königreich" + # Weitere häufige + "japan": "Japan", "jp": "Japan", "nippon": "Japan", "nihon": "Japan", + "kanada": "Kanada", "canada": "Kanada", "ca": "Kanada", + "china": "China", "cn": "China", + "indien": "Indien", "in": "Indien", + "russland": "Russland", "russian federation": "Russland", "ru": "Russland", + "brasilien": "Brasilien", "brazil": "Brasilien", "br": "Brasilien", + "australien": "Australien", "australia": "Australien", "au": "Australien", + "dänemark": "Dänemark", "denmark": "Dänemark", "dk": "Dänemark", + "schweden": "Schweden", "sweden": "Schweden", "se": "Schweden", + "norwegen": "Norwegen", "norway": "Norwegen", "no": "Norwegen", + "finnland": "Finnland", "finland": "Finnland", "fi": "Finnland", + "irland": "Irland", "ireland": "Irland", "ie": "Irland", + "taiwan": "Taiwan", "tw": "Taiwan", + "südkorea": "Südkorea", "south korea": "Südkorea", "kr": "Südkorea", "republic of korea": "Südkorea", + "tschechien": "Tschechien", "czech republic": "Tschechien", "cz": "Tschechien", + "ungarn": "Ungarn", "hungary": "Ungarn", "hu": "Ungarn", + "litauen": "Litauen", "lithuania": "Litauen", "lt": "Litauen", + # ... diese Liste kann und sollte basierend auf Ihren Daten erweitert werden ... } - found_country_in_string = "" - - # Suche nach Land in Klammern am Ende: Stadt (Land) + # Mapping von Bundesländern/Kantonen zu Ländern (Beispiele) + region_to_country = { + "nrw": "Deutschland", "nordrhein-westfalen": "Deutschland", + "bayern": "Deutschland", "bavaria": "Deutschland", + "hessen": "Deutschland", + "baden-württemberg": "Deutschland", "bw": "Deutschland", + "niedersachsen": "Deutschland", + "berlin": "Deutschland", # Berlin ist auch eine Stadt, aber wenn es isoliert steht als Region + "hamburg": "Deutschland", # dito + "sachsen": "Deutschland", + "sachsen-anhalt": "Deutschland", + "thüringen": "Deutschland", + "brandenburg": "Deutschland", + "mecklenburg-vorpommern": "Deutschland", + "rheinland-pfalz": "Deutschland", "rlp": "Deutschland", + "saarland": "Deutschland", + "schleswig-holstein": "Deutschland", "sh": "Deutschland", + "bremen": "Deutschland", + "zg": "Schweiz", "zug": "Schweiz", # Zug ist auch eine Stadt + "zh": "Schweiz", "zürich": "Schweiz", # Zürich ist auch eine Stadt + "be": "Schweiz", "bern": "Schweiz", # Bern ist auch eine Stadt + "ag": "Schweiz", "aargau": "Schweiz", + "sg": "Schweiz", "st. gallen": "Schweiz", + "va": "USA", "virginia": "USA", + "ca": "USA", "california": "USA", # Konflikt mit Kanada, wenn nur "CA" + "ny": "USA", "new york": "USA", # New York ist auch eine Stadt + "il": "USA", "illinois": "USA", + "tx": "USA", "texas": "USA", + "fl": "USA", "florida": "USA", + "pa": "USA", "pennsylvania": "USA", + "oh": "USA", "ohio": "USA", + "ma": "USA", "massachusetts": "USA", + # ... erweitern ... + } + + extracted_country = "" + + # Priorität 1: Land in Klammern am Ende: Stadt (Land) klammer_match = re.search(r'\(([^)]+)\)$', temp_sitz) if klammer_match: potential_land_in_klammer = klammer_match.group(1).strip().lower() - if potential_land_in_klammer in known_countries: - found_country_in_string = known_countries[potential_land_in_klammer] + if potential_land_in_klammer in known_countries_detailed: + extracted_country = known_countries_detailed[potential_land_in_klammer] temp_sitz = temp_sitz[:klammer_match.start()].strip() # Rest ist Stadt + elif potential_land_in_klammer in region_to_country: + extracted_country = region_to_country[potential_land_in_klammer] + temp_sitz = temp_sitz[:klammer_match.start()].strip() - # Wenn kein Land in Klammern, suche nach Komma und bekanntem Land am Ende - if not found_country_in_string and ',' in temp_sitz: + # Priorität 2: Ländercode-Präfix wie D-PLZ, CH-PLZ + if not extracted_country: + prefix_match = re.match(r'^([A-Za-z]{1,3})\s*-\s*\d{4,}', temp_sitz) # z.B. D-12345 oder CH-1234 + if prefix_match: + potential_country_code = prefix_match.group(1).lower() + if potential_country_code in known_countries_detailed: + extracted_country = known_countries_detailed[potential_country_code] + # Entferne den Präfix und die PLZ vom temp_sitz + temp_sitz = re.sub(r'^[A-Za-z]{1,3}\s*-\s*\d{4,}\s*', '', temp_sitz).strip() + + # Priorität 3: Komma-getrennte Liste, Land oder Region am Ende + if not extracted_country and ',' in temp_sitz: parts = [p.strip() for p in temp_sitz.split(',')] if len(parts) > 1: - potential_land_after_comma = parts[-1].lower() - if potential_land_after_comma in known_countries: - found_country_in_string = known_countries[potential_land_after_comma] - temp_sitz = ", ".join(parts[:-1]).strip() # Rest ist Stadt + # Prüfe die letzten Teile auf bekannte Länder oder Regionen + for k in range(len(parts) - 1, 0, -1): # Rückwärts prüfen für längere Übereinstimmungen + potential_suffix = ", ".join(parts[k:]).lower() # z.B. "New York, U.S." oder nur "U.S." + if potential_suffix in known_countries_detailed: + extracted_country = known_countries_detailed[potential_suffix] + temp_sitz = ", ".join(parts[:k]).strip() + break + elif potential_suffix in region_to_country: + extracted_country = region_to_country[potential_suffix] + temp_sitz = ", ".join(parts[:k]).strip() + break + # Wenn nur der letzte Teil geprüft wird (wie vorher) + if not extracted_country: + last_part = parts[-1].lower() + if last_part in known_countries_detailed: + extracted_country = known_countries_detailed[last_part] + temp_sitz = ", ".join(parts[:-1]).strip() + elif last_part in region_to_country: + extracted_country = region_to_country[last_part] + temp_sitz = ", ".join(parts[:-1]).strip() - # Wenn immer noch kein Land, aber der verbleibende String einem Land entspricht - if not found_country_in_string and temp_sitz.lower() in known_countries: - found_country_in_string = known_countries[temp_sitz.lower()] + # Priorität 4: Gesamter String ist ein bekanntes Land (selten, aber möglich) + if not extracted_country and temp_sitz.lower() in known_countries_detailed: + extracted_country = known_countries_detailed[temp_sitz.lower()] temp_sitz = "" # Ganzer String war das Land - sitz_land_val = found_country_in_string if found_country_in_string else "k.A." + # Priorität 5: Teilstring am Ende ist ein Land (z.B. "München Deutschland") + if not extracted_country: + for country_key, country_name in known_countries_detailed.items(): + # Suche nach dem Land am Ende des Strings (ganzes Wort) + if temp_sitz.lower().endswith(f" {country_key}") or temp_sitz.lower() == country_key: + extracted_country = country_name + # Entferne das Land vom Ende des temp_sitz + if temp_sitz.lower().endswith(f" {country_key}"): + temp_sitz = temp_sitz[:-len(f" {country_key}")].strip() + elif temp_sitz.lower() == country_key: + temp_sitz = "" + break - # Was übrig bleibt (oder der Originalstring, falls kein Land getrennt werden konnte), ist die Stadt - # Entferne Postleitzahlen und führende/trailing Whitespace + sitz_land_val = extracted_country if extracted_country else "k.A." + + # Was übrig bleibt, ist die Stadt (nach Entfernung von PLZ, Kommas am Ende) + # Entferne führende/trailing Kommas und Leerzeichen, die durch die Länderentfernung entstehen könnten + temp_sitz = temp_sitz.strip(',').strip() + # Entferne erneut PLZ, falls sie jetzt am Anfang stehen sitz_stadt_val = re.sub(r'^\d{4,8}\s*', '', temp_sitz).strip() - if not sitz_stadt_val and raw_sitz_string.lower() != "k.a." and sitz_land_val == "k.A.": # Wenn Stadt leer, aber Original hatte was und kein Land gefunden - sitz_stadt_val = raw_sitz_string # Nimm Original als Stadt + + if not sitz_stadt_val and raw_sitz_string.lower() != "k.a." and sitz_land_val == "k.A.": + sitz_stadt_val = raw_sitz_string.strip() elif not sitz_stadt_val: sitz_stadt_val = "k.A." + + # Spezifische Korrektur für Fälle wie "München Deutschland" wo Land schon weg ist + if sitz_stadt_val.lower() == sitz_land_val.lower() and sitz_land_val != "k.A.": + # Wenn Stadt und Land identisch sind (z.B. nach Entfernung von "Deutschland" aus "München Deutschland") + # und raw_sitz_string mehr enthielt + if raw_sitz_string.lower() != sitz_land_val.lower(): + sitz_stadt_val = raw_sitz_string.replace(sitz_land_val, '').replace(sitz_land_val.lower(), '').strip(',').strip() + if not sitz_stadt_val: sitz_stadt_val = "k.A." + result = { 'url': page_url,