Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.1 KiB
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:
01_prihlaseni.py— přihlásí se certifikátem, uloží cookies dovozp_cookies.json02_stahuj_vse.py— použije cookies, projde všechny schránky, stáhne soubory doStaž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
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": "<původní challenge text>",
"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:
# 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í.
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í
python 01_prihlaseni.py # přihlásí, uloží cookies
python 02_stahuj_vse.py # stáhne vše nové