116 lines
No EOL
4.4 KiB
Python
116 lines
No EOL
4.4 KiB
Python
import asyncio
|
|
import os
|
|
import re
|
|
from playwright.async_api import async_playwright
|
|
from google import genai
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
# Den nye pakken henter automatisk GEMINI_API_KEY fra .env-filen din
|
|
client = genai.Client()
|
|
|
|
async def ask_llm_status(text, course_name, is_single_course):
|
|
if is_single_course:
|
|
bane_instruks = "Finn den generelle banestatusen for dette golfanlegget. Se bort fra spesifikke banenavn, da anlegget kun har én bane."
|
|
else:
|
|
bane_instruks = f'Finn banestatusen SPESIFIKT for banen som heter/omtales som: "{course_name}".'
|
|
|
|
prompt = f"""
|
|
Du er en ekspert på å lese norske golfklubbers nettsider for å finne banestatus.
|
|
{bane_instruks}
|
|
Svar KUN med nøyaktig ETT av disse ordene:
|
|
- aapen (hvis banen er åpen/sommergreener)
|
|
- stengt (hvis banen er lukket/stengt/frost/snø)
|
|
- aapen_med_vintergreener (hvis det spilles på vintergreener)
|
|
- aapner_snart (hvis den åpner om kort tid)
|
|
- stenger_snart (hvis den stenger for sesongen om kort tid)
|
|
- under_utvikling (hvis den er under utvikling)
|
|
- nedlagt (hvis den er nedlagt)
|
|
- ukjent (hvis du ikke finner noe info om banen i teksten)
|
|
|
|
Tekst fra nettsiden:
|
|
{text[:15000]}
|
|
"""
|
|
|
|
try:
|
|
# Ny måte å kalle modellen asynkront på med google-genai
|
|
response = await client.aio.models.generate_content(
|
|
model='gemini-2.5-flash',
|
|
contents=prompt
|
|
)
|
|
svar = response.text.strip().lower()
|
|
|
|
gyldige_svar = [
|
|
"aapen", "stengt", "aapen_med_vintergreener",
|
|
"aapner_snart", "stenger_snart", "under_utvikling",
|
|
"nedlagt", "ukjent"
|
|
]
|
|
|
|
for gyldig in gyldige_svar:
|
|
if gyldig in svar:
|
|
return gyldig
|
|
return "ukjent"
|
|
except Exception as e:
|
|
print(f"❌ Gemini Feil: {e}")
|
|
return "ukjent"
|
|
|
|
async def run_test():
|
|
print("\n" + "="*50)
|
|
print(" 🧪 TEE OFF: GEMINI TEST-VERKTØY (MED AUTO-KLIKKER)")
|
|
print("="*50)
|
|
|
|
url = input("🌐 Skriv inn URL til golfklubben (f.eks. https://oslogk.no): ").strip()
|
|
if not url.startswith("http"):
|
|
url = "https://" + url
|
|
|
|
course_name = input("⛳ Skriv inn banenavn (eller trykk ENTER hvis anlegget kun har 1 bane): ").strip()
|
|
is_single = len(course_name) == 0
|
|
|
|
print("\n⏳ 1. Starter nettleser og besøker siden...")
|
|
|
|
full_text = ""
|
|
async with async_playwright() as p:
|
|
browser = await p.chromium.launch(headless=True)
|
|
page = await browser.new_page()
|
|
try:
|
|
await page.goto(url, timeout=30000, wait_until="domcontentloaded")
|
|
await asyncio.sleep(3) # Vent på animasjoner og iframes
|
|
|
|
# --- NY LOGIKK: AUTO-KLIKKER ---
|
|
print("🖱️ Leter etter 'banestatus'-knapper å klikke på...")
|
|
# Vi leter etter tekst som inneholder "banestatus" (ignorerer store/små bokstaver)
|
|
knapper = await page.get_by_text(re.compile(r"banestatus", re.IGNORECASE)).all()
|
|
|
|
for knapp in knapper:
|
|
try:
|
|
if await knapp.is_visible():
|
|
await knapp.click(timeout=3000)
|
|
print(" 🎯 Klikket på en banestatus-knapp! Venter 2 sekunder...")
|
|
await asyncio.sleep(2) # Venter på at modalen/pop-upen åpner seg
|
|
break # Vi trenger bare å klikke på den første vi finner
|
|
except Exception as e:
|
|
# Ignorerer hvis knappen ikke er klikkbar, prøver neste
|
|
pass
|
|
# --------------------------------
|
|
|
|
element = page.locator("body").first
|
|
råtekst = await element.inner_text()
|
|
full_text = " ".join(råtekst.split())
|
|
print(f"✅ Hentet {len(full_text)} tegn med tekst fra nettsiden.")
|
|
|
|
except Exception as e:
|
|
print(f"❌ Feil ved innlasting av side: {e}")
|
|
await browser.close()
|
|
return
|
|
await browser.close()
|
|
|
|
print("🧠 2. Sender teksten til Gemini for analyse...")
|
|
status = await ask_llm_status(full_text, course_name, is_single)
|
|
|
|
print("\n" + "="*50)
|
|
print(f"🎯 GEMINI SITT SVAR: {status.upper()}")
|
|
print("="*50 + "\n")
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(run_test()) |