From a5066de46717cc0566842582a895f0007f3b0626 Mon Sep 17 00:00:00 2001 From: Vladimir Buzalka Date: Mon, 20 Apr 2026 07:07:00 +0200 Subject: [PATCH] notebookvb --- .../StahováníZpráv/201 VoZP/01_prihlaseni.py | 252 ++++++++++-------- .../StahováníZpráv/201 VoZP/02_stahuj_vse.py | 26 +- .../StahováníZpráv/201 VoZP/03_stahuj_nove.py | 24 +- .../201 VoZP/start_chrome_debug.bat | 30 +++ 4 files changed, 182 insertions(+), 150 deletions(-) create mode 100644 Insurance/StahováníZpráv/201 VoZP/start_chrome_debug.bat diff --git a/Insurance/StahováníZpráv/201 VoZP/01_prihlaseni.py b/Insurance/StahováníZpráv/201 VoZP/01_prihlaseni.py index 1b60fd2..f2fe7b8 100644 --- a/Insurance/StahováníZpráv/201 VoZP/01_prihlaseni.py +++ b/Insurance/StahováníZpráv/201 VoZP/01_prihlaseni.py @@ -1,140 +1,166 @@ """ -01 - Přihlášení na portál VoZP (prehled-zprav-ve-schrankach) -Otevře Chrome, přihlásí se certifikátem přes Signer komponentu a naviguje na schránku zpráv. -Okno zůstane otevřené — skript čeká na stisk Enter. -Použití: python 01_prihlaseni.py +01 - Přihlášení na portál VoZP — extrakce cookies (jako admin). + +POSTUP: + 1. Spusť: python 01_prihlaseni.py + 2. Vyskočí UAC — schval (skript potřebuje admin pro čtení Chrome cookies + kvůli App-Bound Encryption v Chrome v130+). + 3. Otevře se nové okno s běžícím skriptem (admin). + 4. Skript otevře Chrome (jako user) na VoZP login. + 5. Přihlas se certifikátem (NMSigner vyskočí — klikni ANO). + 6. Vrať se k Chrome → ZAVŘI ho (všechna okna). + 7. Stiskni Enter v admin okně skriptu. + 8. Cookies se uloží do vozp_cookies.json. + +POŽADAVKY: + pip install rookiepy """ +import ctypes import json import os +import subprocess import sys -import time -import winreg -LOGIN_URL = "https://portal.vozp.cz/app/prihlaseni" -INBOX_URL = "https://portal.vozp.cz/app/prehled-zprav-ve-schrankach" -CHROME_PROFILE = os.path.abspath(os.path.join(os.path.dirname(__file__), "chrome_profile")) -COOKIES_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), "vozp_cookies.json")) +LOGIN_URL = "https://portal.vozp.cz/app/prihlaseni" +INBOX_URL = "https://portal.vozp.cz/app/prehled-zprav-ve-schrankach" +COOKIES_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), "vozp_cookies.json")) -def load_cookies(context) -> int: - """Načte dříve uložené cookies zpět do kontextu.""" - if not os.path.exists(COOKIES_FILE): - return 0 +def is_admin() -> bool: try: - with open(COOKIES_FILE, "r", encoding="utf-8") as f: - cookies = json.load(f) - context.add_cookies(cookies) - return len(cookies) - except Exception as e: - print(f" Chyba při načítání cookies: {e}") - return 0 + return ctypes.windll.shell32.IsUserAnAdmin() != 0 + except Exception: + return False -def save_cookies(context) -> int: - """Uloží VoZP cookies (i session-only) do JSON souboru.""" +def relaunch_as_admin() -> None: + print("Skript potřebuje admin práva (Chrome v130+ App-Bound Encryption).") + print("Otevírám UAC...") + params = " ".join(f'"{a}"' for a in sys.argv) + ret = ctypes.windll.shell32.ShellExecuteW( + None, "runas", sys.executable, params, None, 1 + ) + if ret <= 32: + print(f"UAC selhalo (kód {ret}). Spusť ručně jako admin.") + sys.exit(1) + sys.exit(0) + + +def open_chrome_as_user(url: str) -> None: + """Spustí default browser jako standardní user, i když Python běží jako admin.""" + # explorer.exe běží jako user a otevře URL v defaultním prohlížeči try: - all_cookies = context.cookies() - vozp = [c for c in all_cookies if any( - d in c.get("domain", "") for d in ["vozp.cz", "portalzp.cz"] - )] - with open(COOKIES_FILE, "w", encoding="utf-8") as f: - json.dump(vozp, f, indent=2, ensure_ascii=False) - return len(vozp) - except Exception as e: - print(f" Chyba při ukládání cookies: {e}") - return 0 - - -def _delete_chrome_cert_policy() -> None: - """Smaže AutoSelectCertificateForUrls politiku — Chrome pak zobrazí dialog přirozeně.""" - key_path = r"SOFTWARE\Policies\Google\Chrome\AutoSelectCertificateForUrls" - try: - key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path, access=winreg.KEY_SET_VALUE) - winreg.DeleteValue(key, "1") - winreg.CloseKey(key) + subprocess.Popen(["explorer.exe", url]) + return except Exception: pass + # Fallback + import webbrowser + webbrowser.open(url) + + +def read_cookies_rookiepy() -> list[dict]: + import rookiepy + raw = rookiepy.chrome(["vozp.cz", ".vozp.cz", "portal.vozp.cz", "portalzp.cz"]) + out = [] + for c in raw: + dom = c["domain"] + if not any(d in dom for d in ["vozp.cz", "portalzp.cz"]): + continue + out.append({ + "name": c["name"], + "value": c["value"], + "domain": dom if dom.startswith(".") else "." + dom, + "path": c.get("path") or "/", + "expires": int(c["expires"]) if c.get("expires") else -1, + "secure": bool(c.get("secure", False)), + "httpOnly": bool(c.get("http_only", False)), + "sameSite": "Lax", + }) + return out + + +def read_cookies_browser_cookie3() -> list[dict]: + import browser_cookie3 + cj = browser_cookie3.chrome(domain_name="vozp.cz") + out = [] + for c in cj: + if not any(d in c.domain for d in ["vozp.cz", "portalzp.cz"]): + continue + out.append({ + "name": c.name, + "value": c.value, + "domain": c.domain if c.domain.startswith(".") else "." + c.domain, + "path": c.path or "/", + "expires": int(c.expires) if c.expires else -1, + "secure": bool(c.secure), + "httpOnly": False, + "sameSite": "Lax", + }) + return out def main() -> None: + if not is_admin(): + relaunch_as_admin() + return # nedosažitelné + + print("=" * 60) + print("BĚŽÍM JAKO ADMIN — PŘIHLÁŠENÍ DO VoZP") + print("=" * 60) + print(f"1. Otevírám Chrome (jako user) na: {LOGIN_URL}") + print("2. Přihlas se certifikátem (NMSigner → klikni ANO)") + print("3. Po přihlášení ZAVŘI Chrome úplně (všechna okna)") + print("4. Vrať se sem a stiskni Enter") + print("=" * 60) + + open_chrome_as_user(LOGIN_URL) + + input("\nAž jsi přihlášen/a a Chrome ZAVŘENÝ, stiskni Enter...") + + cookies: list[dict] = [] + last_err = "" + + print("\nČtu cookies (jako admin)...") try: - from playwright.sync_api import sync_playwright + cookies = read_cookies_rookiepy() + print(f" rookiepy OK: {len(cookies)} cookies") except ImportError: - print("Chybí playwright: pip install playwright && playwright install chrome") + last_err = "rookiepy není nainstalovaný" + print(f" {last_err} — zkouším browser_cookie3...") + except Exception as e: + last_err = f"rookiepy: {e}" + print(f" rookiepy selhalo: {e} — zkouším browser_cookie3...") + + if not cookies: + try: + cookies = read_cookies_browser_cookie3() + print(f" browser_cookie3 OK: {len(cookies)} cookies") + except ImportError: + print(" browser_cookie3 není nainstalovaný.") + except Exception as e: + print(f" browser_cookie3: {e}") + + if not cookies: + print("\nCookies se nepodařilo přečíst ani jako admin.") + print("Zkontroluj, že:") + print(" - Chrome je úplně zavřený (Task Manager → žádný chrome.exe)") + print(" - Jsi se na VoZP přihlásil/a (DB má nové záznamy)") + print(" - Máš nainstalované: pip install rookiepy browser-cookie3") + input("\nEnter pro zavření...") sys.exit(1) - _delete_chrome_cert_policy() + with open(COOKIES_FILE, "w", encoding="utf-8") as f: + json.dump(cookies, f, indent=2, ensure_ascii=False) - with sync_playwright() as p: - context = p.chromium.launch_persistent_context( - user_data_dir=CHROME_PROFILE, - channel="chrome", - headless=False, - slow_mo=200, - ignore_https_errors=True, - args=["--force-renderer-accessibility"], - ) - try: - loaded = load_cookies(context) - print(f"Profil: {CHROME_PROFILE}") - print(f"Cookies z JSON: {loaded}") + print(f"\nUloženo {len(cookies)} cookies do {COOKIES_FILE}") + for c in cookies: + exp = c["expires"] + tag = "PERSISTENT" if exp > 0 else "SESSION" + print(f" - {c['name'][:50]} ({c['domain']}) [{tag}]") - page = context.new_page() - - # Zkus rovnou inbox — pokud jsme přihlášeni, budeme tam - print("Naviguji na schránku zpráv...") - try: - page.goto(INBOX_URL, wait_until="domcontentloaded", timeout=30_000) - except Exception as e: - print(f"Navigace: {e}") - - # Pokud nás přesměrovalo na login stránku - if "prihlaseni" in page.url or "login" in page.url.lower(): - print("Přihlašovací stránka — klikám na 'Přihlásit se certifikátem'...") - try: - page.goto(LOGIN_URL, wait_until="domcontentloaded", timeout=30_000) - except Exception as e: - print(f"Navigace na login: {e}") - - cert_btn = page.locator("button").filter(has_text="certifikátem").first - cert_btn.wait_for(state="visible", timeout=10_000) - cert_btn.click(no_wait_after=True) - - print("Vyskočí Signer komponenta — klikněte ANO (max 60 s)...") - time.sleep(30) - - # Po Signeru naviguj na inbox - print("Naviguji na schránku zpráv...") - try: - page.goto(INBOX_URL, wait_until="domcontentloaded", timeout=30_000) - except Exception as e: - print(f"Navigace po auth: {e}") - - if "prehled-zprav" not in page.url and "uvodni-stranka" not in page.url: - print(f"Přihlášení selhalo. URL: {page.url}") - return - - print(f"OK — přihlášení úspěšné. URL: {page.url}") - - # Diagnostika cookies - after = context.cookies() - vozp_cookies = [c for c in after if any( - d in c.get("domain", "") for d in ["vozp.cz", "portalzp.cz"] - )] - print(f"Cookies po auth: {len(vozp_cookies)}") - for c in vozp_cookies: - exp = c.get("expires", -1) - persistent = "PERSISTENT" if exp > 0 else "SESSION-ONLY" - print(f" - {c['name'][:60]} ({c['domain']}) [{persistent}]") - - print("Okno zůstane otevřené. Stiskněte Enter pro zavření...") - input() - - finally: - saved = save_cookies(context) - print(f"Uloženo {saved} VoZP cookies do {COOKIES_FILE}") - context.close() + input("\nHotovo. Enter pro zavření...") if __name__ == "__main__": diff --git a/Insurance/StahováníZpráv/201 VoZP/02_stahuj_vse.py b/Insurance/StahováníZpráv/201 VoZP/02_stahuj_vse.py index 4416ea9..a643b1f 100644 --- a/Insurance/StahováníZpráv/201 VoZP/02_stahuj_vse.py +++ b/Insurance/StahováníZpráv/201 VoZP/02_stahuj_vse.py @@ -232,32 +232,20 @@ def process_schránka(page, session: req.Session, segment: str, name: str, alrea def ensure_logged_in(page, context) -> bool: - """Ověří přihlášení. Pokud ne, provede přihlášení certifikátem.""" + """Ověří přihlášení. Pokud cookies nestačí, upozorní na spuštění 01.""" try: page.goto(INBOX_URL, wait_until="domcontentloaded", timeout=30_000) except Exception as e: print(f"Navigace: {e}") if "prihlaseni" in page.url or "login" in page.url.lower(): - print("Nutné přihlášení — klikám na 'Přihlásit se certifikátem'...") - try: - page.goto(LOGIN_URL, wait_until="domcontentloaded", timeout=30_000) - except Exception: - pass - cert_btn = page.locator("button").filter(has_text="certifikátem").first - cert_btn.wait_for(state="visible", timeout=10_000) - cert_btn.click(no_wait_after=True) - print("Vyskočí Signer komponenta — klikněte ANO (max 60 s)...") - time.sleep(40) - try: - page.goto(INBOX_URL, wait_until="domcontentloaded", timeout=30_000) - except Exception: - pass - if "prihlaseni" in page.url: - print("Přihlášení selhalo.") - return False + print("=" * 60) + print("Cookies neplatné nebo vypršely.") + print("Spusť znovu: python 01_prihlaseni.py") + print("=" * 60) + return False - print(f"Přihlášení OK. URL: {page.url}") + print(f"Přihlášení OK (přes cookies). URL: {page.url}") return True diff --git a/Insurance/StahováníZpráv/201 VoZP/03_stahuj_nove.py b/Insurance/StahováníZpráv/201 VoZP/03_stahuj_nove.py index 2fccecc..b8c1b28 100644 --- a/Insurance/StahováníZpráv/201 VoZP/03_stahuj_nove.py +++ b/Insurance/StahováníZpráv/201 VoZP/03_stahuj_nove.py @@ -235,25 +235,13 @@ def ensure_logged_in(page, context) -> bool: print(f"Navigace: {e}") if "prihlaseni" in page.url or "login" in page.url.lower(): - print("Nutné přihlášení — klikám na 'Přihlásit se certifikátem'...") - try: - page.goto(LOGIN_URL, wait_until="domcontentloaded", timeout=30_000) - except Exception: - pass - cert_btn = page.locator("button").filter(has_text="certifikátem").first - cert_btn.wait_for(state="visible", timeout=10_000) - cert_btn.click(no_wait_after=True) - print("Vyskočí Signer komponenta — klikněte ANO (max 60 s)...") - time.sleep(40) - try: - page.goto(INBOX_URL, wait_until="domcontentloaded", timeout=30_000) - except Exception: - pass - if "prihlaseni" in page.url: - print("Přihlášení selhalo.") - return False + print("=" * 60) + print("Cookies neplatné nebo vypršely.") + print("Spusť znovu: python 01_prihlaseni.py") + print("=" * 60) + return False - print(f"Přihlášení OK. URL: {page.url}") + print(f"Přihlášení OK (přes cookies). URL: {page.url}") return True diff --git a/Insurance/StahováníZpráv/201 VoZP/start_chrome_debug.bat b/Insurance/StahováníZpráv/201 VoZP/start_chrome_debug.bat new file mode 100644 index 0000000..4cf1448 --- /dev/null +++ b/Insurance/StahováníZpráv/201 VoZP/start_chrome_debug.bat @@ -0,0 +1,30 @@ +@echo off +REM Spustí Chrome s otevřeným CDP portem 9222 pro extrakci cookies. +REM Před spuštěním ukončí všechny běžící Chrome procesy +REM (Chrome neumožňuje dvě instance nad stejným profilem). + +echo Ukoncuji bezici Chrome procesy... +taskkill /f /im chrome.exe >nul 2>&1 +timeout /t 2 /nobreak >nul + +set "CHROME_EXE=C:\Program Files\Google\Chrome\Application\chrome.exe" +if not exist "%CHROME_EXE%" set "CHROME_EXE=C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" +if not exist "%CHROME_EXE%" set "CHROME_EXE=%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe" + +echo Spoustim Chrome s debug portem 9222... +start "" "%CHROME_EXE%" ^ + --remote-debugging-port=9222 ^ + --remote-allow-origins=* ^ + --user-data-dir="%LOCALAPPDATA%\Google\Chrome\User Data" ^ + --profile-directory="Default" ^ + --restore-last-session=false ^ + --hide-crash-restore-bubble ^ + --no-first-run ^ + --no-default-browser-check ^ + https://portal.vozp.cz/app/prihlaseni + +echo. +echo Chrome se spousti. Po prihlaseni do VoZP spust: +echo python 01_prihlaseni.py +echo. +pause