# VoZP — Automatické stahování zpráv ## Co to dělá Dva skripty které se přihlásí na portál VoZP a stáhnou všechny zprávy ze schránek: 1. `01_prihlaseni.py` — přihlásí se certifikátem, uloží cookies do `vozp_cookies.json` 2. `02_stahuj_vse.py` — použije cookies, projde všechny schránky, stáhne soubory do `Staženo/` --- ## Jak funguje přihlášení (challenge-response) Portál **nepoužívá heslo** — autentizuje certifikátem přes 4 kroky: ### Krok 1 — Získej session ``` GET https://portal.vozp.cz/app/prihlaseni → server nastaví cookie: SID=... ``` Ručně nastav cookie: `pzp_sign=CERT` (říká serveru, že chceš certifikát) ### Krok 2 — Získej challenge ``` POST /json-api/prihlaseni/prihlasovaci-zprava Body: {"login_sign": "CERT"} Odpověď: { "data": { "zprava": "Prohlášení:\r\nTímto se přihlašuji k Portálu VOZP ČR\r\n\r\nOkamžik vygenerování ... mikrosekundu: 20.04.2026 13:22:34.058119" } } ``` ### Krok 3 — Podepis certifikátem Zprávu z kroku 2 podepíš jako **PKCS7 / CMS SignedData**: - Algoritmus: **RSA + SHA-256** - Typ: **DetachedSignature** (obsah není vložen do podpisu) - **BEZ CA řetězu** — pouze end-entity certifikát, žádné CA certifikáty ```python podpis = ( pkcs7.PKCS7SignatureBuilder() .set_data(zprava.encode("utf-8")) .add_signer(cert, private_key, hashes.SHA256()) .sign(Encoding.PEM, [PKCS7Options.DetachedSignature]) ) ``` > ⚠️ Přidání CA řetězu způsobí chybu "neznámý klientský certifikát" — i když thumbprint sedí! ### Krok 4 — Přihlášení ``` POST /json-api/prihlaseni/prihlaseni-certifikatem Body: { "zprava": "", "podpis": "-----BEGIN PKCS7-----\n...\n-----END PKCS7-----" } Úspěch: {"data": {"prihlasen": true, "url": "/app/uvodni-stranka"}} ``` --- ## Certifikát | Položka | Hodnota | |---|---| | Soubor | `U:\ordinaceprojekt\Insurance\Certificates\MBQualifiedCert.pfx` | | Vlastník | MUDr. Michaela Buzalková | | Vydavatel | I.CA EU Qualified CA2/RSA 06/2022 | | Platnost | do 2027-01-16 | | Thumbprint | `056ED80A3CDDE31DD36EECE0181B4E78D61122A7` | | Serial (hex) | `0247068517B0049E2E` | Jak exportovat správný certifikát z Windows: ```powershell # Najdi certifikát podle thumbprintu $cert = Get-ChildItem Cert:\CurrentUser\My | Where-Object {$_.Thumbprint -eq "056ED80A3CDDE31DD36EECE0181B4E78D61122A7"} $pwd = Read-Host "Heslo" -AsSecureString Export-PfxCertificate -Cert $cert -FilePath "MBQualifiedCert.pfx" -Password $pwd ``` > Při exportu: PKCS #12, **nezaškrtávej** "Include all certificates in the certification path" --- ## Stahování souborů `02_stahuj_vse.py` používá **Playwright** (viditelný Chrome) pro navigaci + `context.request.get()` pro stahování. Endpoint stahování: ``` GET /html/prehled-zprav-ve-schrankach/zobrazit-prilohu?zprava_id={id} ``` ### Schránky které se prochází | Segment URL | Název | |---|---| | `171-schranka-poskytovatele-zdravotnich-sluzeb` | Schránka PZS | | `183-schranka-klientu-portalu` | Schránka klientů portálu | | `185-schranka-pzs` | Schránka PZS2 | | `187-schranka-klienta` | Schránka klienta | | `198-vypis-registrovanych-pacientu` | Výpis registrovaných pacientů | | `200-zuctovaci-zpravy` | Zúčtovací zprávy | | `205-vypis-osobnich-uctu-pojistencu` | Výpis osobních účtů pojištěnců | ### Paginace — důležité Portál při přetečení stránek (např. stranka-16 když existuje jen 15) **vrátí poslední stránku znovu** místo prázdné. Detekce: sleduj `fileId` napříč stránkami, zastav při opakování. ```python current_ids = {r["fileId"] for r in rows} if current_ids & seen_ids: break # opakující se obsah = konec seen_ids.update(current_ids) ``` --- ## Pojmenování stažených souborů ``` YYYY-MM-DD Popis zprávy (původní_název_souboru).přípona ``` Příklad: `2026-04-15 Odpověď na podání č. 176867777 (Protokol-OK).html` --- ## Závislosti ``` pip install requests cryptography playwright playwright install chrome ``` --- ## Spuštění ```bash python 01_prihlaseni.py # přihlásí, uloží cookies python 02_stahuj_vse.py # stáhne vše nové ```