763e06c127
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
58 lines
3.7 KiB
Markdown
58 lines
3.7 KiB
Markdown
# consent — CMP / IAB TCF / data brokers
|
|
|
|
Operar banners de consentimiento (Consent Management Platforms) y el ecosistema IAB TCF:
|
|
detectar qué CMP usa un sitio, leer cuántos *vendors* (data brokers) declara, aceptar el
|
|
banner cuando hace falta y cruzar los IDs de vendor contra la Global Vendor List de IAB para
|
|
nominar a cada broker y describir qué datos personales recopila.
|
|
|
|
Nació de la investigación `projects/databrokers/` (data brokers de la prensa española).
|
|
|
|
## Funciones del grupo
|
|
|
|
| ID | Firma corta | Qué hace |
|
|
|---|---|---|
|
|
| `extract_cmp_tcf_py_browser` | `extract_cmp_tcf(url, *, port=9222, accept_first=False, llm_fallback=False, ...) -> dict` | Navega a `url` por CDP, detecta el CMP (Didomi/OneTrust/Sourcepoint/Quantcast/otro_tcf), lee `window.__tcfapi` y devuelve nº de vendors, propósitos, muro "pago o consientes" y `vendor_ids`. Con `accept_first` acepta el banner antes de leer; con `llm_fallback` recurre a `find_consent_controls_llm` si el clic por selector falla. |
|
|
| `find_consent_controls_llm_py_browser` | `find_consent_controls_llm(*, port=9222, max_candidates=40, model="claude-haiku-4-5-20251001") -> dict` | Recolecta los controles clicables del banner (los marca con `data-fnllm="N"`) y pregunta a un LLM (haiku) cuál es Aceptar / Rechazar / Ver socios. Devuelve los selectores. Resuelve CMP con clases dinámicas/texto no estándar sin selectores hardcodeados. |
|
|
| `fetch_iab_gvl_py_cybersecurity` | `fetch_iab_gvl(out_path="", url="", lang="") -> dict` | Descarga y parsea la Global Vendor List de IAB (catálogo maestro de vendors: nombre, propósitos, `dataDeclaration`, retención, política). Endpoint v3 con fallback v2. |
|
|
|
|
## Ejemplo canónico (end-to-end)
|
|
|
|
Escanear un medio, contar sus brokers y nombrarlos cruzando con la GVL:
|
|
|
|
```python
|
|
import sys; sys.path.insert(0, "python/functions")
|
|
from browser.extract_cmp_tcf import extract_cmp_tcf
|
|
from cybersecurity.fetch_iab_gvl import fetch_iab_gvl
|
|
|
|
# 1. Catálogo maestro de vendors (una vez).
|
|
gvl = fetch_iab_gvl(out_path="/tmp/gvl.json") # {status, vendors:{id:{name,purposes,...}}, ...}
|
|
|
|
# 2. Escanear un sitio (Chrome con CDP en el puerto indicado; perfil limpio para que salga el banner).
|
|
# accept_first acepta el banner; llm_fallback usa haiku si el botón no encaja con selectores fijos.
|
|
scan = extract_cmp_tcf("https://www.lavanguardia.com", port=9335,
|
|
accept_first=True, llm_fallback=True)
|
|
# scan -> {status, cmp:'didomi', n_vendors:1092, vendor_ids:[...], paywall_consent:True, ...}
|
|
|
|
# 3. Nominar los brokers de ese medio.
|
|
nombres = [gvl["vendors"].get(str(v), {}).get("name", f"(vendor {v})") for v in scan["vendor_ids"]]
|
|
```
|
|
|
|
Orquestador completo sobre un censo de dominios: `projects/databrokers/scanner/scan_all.py`
|
|
(itera → `extract_cmp_tcf` → persiste → cruza con la GVL → Excel).
|
|
|
|
## Prerrequisitos
|
|
|
|
- Un Chrome/Chromium con remote debugging (CDP) en el puerto usado. Lánzalo aislado del navegador
|
|
diario (no 9222) con su propio `user_data_dir`. **Perfil limpio**: una vez aceptado el banner,
|
|
la cookie de consent persiste en el perfil y los re-escaneos ya no muestran banner.
|
|
- `ask_llm` (grupo `claude-direct`) requiere el token OAuth de Claude Max en `~/.claude/.credentials.json`.
|
|
|
|
## Fronteras (lo que el grupo NO cubre)
|
|
|
|
- No extrae la lista de vendors de CMP cuyo `getTCData` no rellena `vendor.consents`/`legitimateInterests`
|
|
por la vía estándar, ni de banners alojados en iframe (Sourcepoint): el clic desde el documento
|
|
principal no alcanza el iframe.
|
|
- No interpreta el `tcString` (qué propósitos consintió el usuario en concreto); solo el universo de
|
|
vendors declarado. Para decodificar el TCString haría falta una pieza aparte.
|
|
- No es un bloqueador ni un gestor de consentimiento propio: solo observa y mide.
|