#!/usr/bin/env python3 # -*- coding: utf-8 -*- from playwright.sync_api import sync_playwright import json import requests STATE_FILE = "medevio_storage.json" AGENDA_URL = ( "https://my.medevio.cz/mudr-buzalkova/klinika/kalendar/agenda-dne/" "?kalendar=144c4e12-347c-49ca-9ec0-8ca965a4470d&datum=2025-10-17" ) GRAPHQL_URL = "https://api.medevio.cz/graphql" def extract_agenda_rows(page): rows = page.locator("div[data-testid='reservation-row']") if rows.count() == 0: raise SystemExit("āŒ No rows found — check selector or login session.") results = [] print(f"\nFound {rows.count()} rows, showing sample structure:") for row in rows.all()[:3]: print("-" * 80) print(row.evaluate("el => el.outerHTML")[:500], "...\n") # Now extract data safely for row in rows.all(): rid = row.get_attribute("data-id") or "" # Try to read each cell dynamically cells = row.locator("div.MuiDataGrid-cell") record = {"id": rid} for c in cells.all(): field = c.get_attribute("data-field") or "unknown" text = (c.text_content() or "").strip() record[field] = text results.append(record) return results def step1_extract_appointments(): with sync_playwright() as pw: browser = pw.chromium.launch(headless=False, slow_mo=150) context = browser.new_context(storage_state=STATE_FILE) page = context.new_page() print("šŸ”— Opening Medevio agenda-day page...") page.goto(AGENDA_URL, wait_until="networkidle", timeout=90_000) page.wait_for_selector("div[data-testid='reservation-row']", timeout=30_000) appointments = extract_agenda_rows(page) browser.close() print(f"āœ… Extracted {len(appointments)} appointments") for a in appointments: print(f"— {a.get('StartDateTime','?')} {a.get('Patient','?')}: {a.get('Reason','?')} ({a['id']})") return appointments def step2_fetch_detail(session_cookies, reservation_id): headers = { "content-type": "application/json", "origin": "https://my.medevio.cz", "referer": "https://my.medevio.cz/", } query = { "operationName": "ReservationDetail", "variables": {"id": reservation_id}, "query": """ query ReservationDetail($id: ID!) { reservation(id: $id) { id reason startDateTime endDateTime status note patient { id name age } doctor { id name } location { name } } } """, } print(f"\nšŸ“” Fetching GraphQL detail for {reservation_id}...") response = requests.post(GRAPHQL_URL, headers=headers, cookies=session_cookies, data=json.dumps(query)) print("Status:", response.status_code) print(json.dumps(response.json(), indent=2, ensure_ascii=False)) if __name__ == "__main__": appointments = step1_extract_appointments() if not appointments: raise SystemExit("No appointments found.") # Use first appointment for detail fetch reservation_id = appointments[0]["id"] # Load session cookies from storage with open(STATE_FILE, "r", encoding="utf-8") as f: state = json.load(f) cookies = {c["name"]: c["value"] for c in state.get("cookies", []) if "medevio" in c["domain"]} step2_fetch_detail(cookies, reservation_id)