165 lines
6.7 KiB
Python
165 lines
6.7 KiB
Python
# Neue Version mit Token-Optimierung, festem Prompt und Begrenzung der Durchläufe
|
||
|
||
import os
|
||
import time
|
||
import pandas as pd
|
||
import gspread
|
||
import openai
|
||
import wikipedia
|
||
from bs4 import BeautifulSoup
|
||
import requests
|
||
from oauth2client.service_account import ServiceAccountCredentials
|
||
from datetime import datetime
|
||
|
||
# === KONFIGURATION ===
|
||
EXCEL = "Bestandsfirmen.xlsx" # optional, falls du später exportieren willst
|
||
SHEET_URL = "https://docs.google.com/spreadsheets/d/1u_gHr9JUfmV1-iviRzbSe3575QEp7KLhK5jFV_gJcgo"
|
||
CREDENTIALS = "service_account.json"
|
||
LANG = "de"
|
||
DURCHLÄUFE = int(input("Wieviele Zeilen sollen überprüft werden? "))
|
||
|
||
# === GOOGLE SHEET VERBINDUNG ===
|
||
scope = ["https://www.googleapis.com/auth/spreadsheets"]
|
||
creds = ServiceAccountCredentials.from_json_keyfile_name(CREDENTIALS, scope)
|
||
sheet = gspread.authorize(creds).open_by_url(SHEET_URL).sheet1
|
||
sheet_values = sheet.get_all_values()
|
||
|
||
# === WIKIPEDIA KONFIG ===
|
||
wikipedia.set_lang(LANG)
|
||
|
||
# === SYSTEM PROMPT ===
|
||
branches = [
|
||
"Hersteller / Produzenten > Maschinenbau",
|
||
"Hersteller / Produzenten > Automobil",
|
||
"Hersteller / Produzenten > Anlagenbau",
|
||
"Hersteller / Produzenten > Medizintechnik",
|
||
"Hersteller / Produzenten > Chemie & Pharma",
|
||
"Hersteller / Produzenten > Elektrotechnik",
|
||
"Hersteller / Produzenten > Lebensmittelproduktion",
|
||
"Hersteller / Produzenten > IT / Telekommunikation",
|
||
"Hersteller / Produzenten > Bürotechnik",
|
||
"Hersteller / Produzenten > Automaten (Vending, Slot)",
|
||
"Hersteller / Produzenten > Gebäudetechnik Heizung, Lüftung, Klima",
|
||
"Hersteller / Produzenten > Gebäudetechnik Allgemein",
|
||
"Hersteller / Produzenten > Schädlingsbekämpfung",
|
||
"Hersteller / Produzenten > Fertigung",
|
||
"Hersteller / Produzenten > Braune & Weiße Ware",
|
||
"Versorger > Stadtwerk",
|
||
"Versorger > Verteilnetzbetreiber",
|
||
"Versorger > Telekommunikation",
|
||
"Dienstleister > Messdienstleister",
|
||
"Dienstleister > Facility Management",
|
||
"Dienstleister > Healthcare/Pflegedienste",
|
||
"Dienstleister > Servicedienstleister / Reparatur ohne Produktion",
|
||
"Handel & Logistik > Auslieferdienste",
|
||
"Handel & Logistik > Energie (Brennstoffe)",
|
||
"Handel & Logistik > Großhandel",
|
||
"Handel & Logistik > Einzelhandel",
|
||
"Handel & Logistik > Logistik Sonstige",
|
||
"Sonstige > Unternehmensberatung (old)",
|
||
"Sonstige > Sonstige",
|
||
"Sonstige > Agrar, Pellets (old)",
|
||
"Sonstige > Sonstiger Service (old)",
|
||
"Sonstige > IT Beratung",
|
||
"Sonstige > Engineering",
|
||
"Baubranche > Baustoffhandel",
|
||
"Baubranche > Baustoffindustrie",
|
||
"Baubranche > Logistiker Baustoffe",
|
||
"Baubranche > Bauunternehmen",
|
||
"Gutachter / Versicherungen > Versicherungsgutachten",
|
||
"Gutachter / Versicherungen > Technische Gutachter",
|
||
"Gutachter / Versicherungen > Medizinische Gutachten"
|
||
]
|
||
|
||
system_prompt = {
|
||
"role": "system",
|
||
"content": (
|
||
"Du bist ein Experte für Brancheneinstufung und FSM-Potenzialbewertung. "
|
||
"FSM steht für Field Service Management – Software zur Planung und Unterstützung mobiler Techniker. "
|
||
"Ziel ist es, Unternehmen zu identifizieren, die mehr als 50 Techniker im Außeneinsatz beschäftigen (z. B. Servicetechniker, Instandhalter, Medizintechniker etc.).\n\n"
|
||
"Dir liegt pro Unternehmen eine strukturierte Eingabezeile vor, bestehend aus:\n"
|
||
"Firmenname; Website; Ort; Aktuelle Einstufung; Beschreibung der Branche Extern\n\n"
|
||
"Bitte führe für jede Firma eine fundierte Bewertung durch:\n"
|
||
"- Nimm eine Brancheneinstufung anhand des untenstehenden Ziel-Branchenschemas vor.\n"
|
||
"- Berücksichtige dabei alle vorliegenden Informationen (auch externe Beschreibung, Wikipedia, LinkedIn, Website) sowie die bisherige Einstufung.\n"
|
||
"- Wenn die bisherige Einstufung korrekt ist, bestätige sie – wenn nicht, schlage eine neue Einstufung vor und begründe diese.\n"
|
||
"- Gib zusätzlich an, ob das Unternehmen FSM-relevant ist (Ja / Nein / k.A. mit Begründung).\n"
|
||
"- Schätze die Anzahl mobiler Techniker anhand öffentlich verfügbarer Infos und gib eine Stufe an: <50 / >50 / >100 / >500, mit Begründung.\n\n"
|
||
"Ziel-Branchenschema:\n" + "\n".join(branches)
|
||
)
|
||
}
|
||
|
||
# === HILFSFUNKTIONEN ===
|
||
def get_wikipedia_data(name):
|
||
for suchbegriff in [name.strip(), " ".join(name.split()[:2])]:
|
||
try:
|
||
page = wikipedia.page(suchbegriff, auto_suggest=False)
|
||
url = page.url
|
||
html = requests.get(url).text
|
||
soup = BeautifulSoup(html, 'html.parser')
|
||
infobox = soup.find("table", {"class": "infobox"})
|
||
branche = umsatz = ""
|
||
if infobox:
|
||
for row in infobox.find_all("tr"):
|
||
th, td = row.find("th"), row.find("td")
|
||
if not th or not td:
|
||
continue
|
||
if "Branche" in th.text:
|
||
branche = td.text.strip()
|
||
if "Umsatz" in th.text:
|
||
umsatz = td.text.strip()
|
||
if not branche:
|
||
cats = page.categories
|
||
branche = cats[0] if cats else ""
|
||
return url, branche, umsatz
|
||
except:
|
||
continue
|
||
return "", "", ""
|
||
|
||
def classify_company(row):
|
||
user_prompt = {
|
||
"role": "user",
|
||
"content": f"{row[0]};{row[1]};{row[2]};{row[4]};{row[5]}"
|
||
}
|
||
response = openai.chat.completions.create(
|
||
model="gpt-3.5-turbo",
|
||
messages=[system_prompt, user_prompt],
|
||
temperature=0
|
||
)
|
||
parts = [v.strip().strip('"') for v in response.choices[0].message.content.strip().split(";", 7)]
|
||
while len(parts) < 8:
|
||
parts.append("k.A.")
|
||
return parts
|
||
|
||
# === STARTINDEX SUCHEN ===
|
||
filled = [row[11] if len(row) > 11 else '' for row in sheet_values[1:]]
|
||
start = next((i + 1 for i, v in enumerate(filled, start=1) if not v.strip()), len(filled) + 1)
|
||
print(f"Starte bei Zeile {start+1}")
|
||
|
||
# === VERARBEITUNG ===
|
||
for i in range(start, min(start + DURCHLÄUFE, len(sheet_values))):
|
||
row = sheet_values[i]
|
||
print(f"[{time.strftime('%H:%M:%S')}] Verarbeite Zeile {i+1}: {row[0]}")
|
||
|
||
url, wiki_branche, umsatz = get_wikipedia_data(row[0])
|
||
wiki, linkedin, umsatz_chat, new_cat, reason, fsm, techniker, techniker_reason = classify_company(row)
|
||
|
||
values = [
|
||
wiki or wiki_branche,
|
||
linkedin,
|
||
umsatz_chat or umsatz,
|
||
new_cat,
|
||
reason,
|
||
fsm,
|
||
url,
|
||
datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
||
techniker,
|
||
techniker_reason
|
||
]
|
||
|
||
# Schreibe in die Spalten G bis P (7–16, nullbasiert also 6–15)
|
||
sheet.update(range_name=f"G{i+2}:P{i+2}", values=[values])
|
||
time.sleep(5)
|
||
|
||
print("✅ Durchläufe abgeschlossen")
|