Registro operativo aggiornato al 1 agosto 2026. Serve a rifare gli stessi passaggi fra un mese senza ricominciare da capo, e soprattutto a ricordare dove l’accesso si rompe e come si aggira.
| Fonte | Cosa succede con curl |
Cosa funziona |
|---|---|---|
www.senato.it |
HTTP 202 con challenge JavaScript («we need to verify that you’re not a robot») | browser vero: agent-browser --headed con
DISPLAY verso X410 |
www.camera.it, documenti.camera.it |
risponde normalmente | curl con user-agent da browser |
www.garanteprivacy.it |
risponde normalmente | curl, oppure Brave Search API per trovare il doc-web
giusto |
Il repertorio dei dati parlamentari: https://github.com/ondata/italianparliament-mcp
Commissioni della Camera, per ricavare l’URI dell’organo:
italianparliament committees list --chamber camera --legislature 19 | grep -iE "affari costituzionali|giustizia"
# I Affari costituzionali → http://dati.camera.it/ocd/organo.rdf/o19_3501
# II Giustizia → http://dati.camera.it/ocd/organo.rdf/o19_3502
Componenti di una commissione, con ruolo e date:
italianparliament committee-members list \
--committee-uri http://dati.camera.it/ocd/organo.rdf/o19_3501 \
--chamber camera --legislature 19 --limit 200 --format csv > camera-I-membri.csv
Gruppi di appartenenza e anagrafica con circoscrizione di elezione:
italianparliament group-members list --legislature 19 --limit 900 --format csv > camera-gruppi.csv
italianparliament deputies list --legislature 19 --limit 900 --format csv > camera-deputati.csv
Atti del Governo al Senato:
italianparliament documents list --legislature 19 --type 'Atto del Governo' --limit 200
Sedute di commissione. L’endpoint SPARQL del Senato ha restituito un
403 intorno alle 18 del 1 agosto e ha ripreso a rispondere
poco dopo, senza che cambiasse nulla nella richiesta: è un
errore transitorio, la reazione giusta è riprovare, non cercare
un’altra strada. Verificato funzionante alle 19:30 dello stesso giorno,
con le sedute aggiornate al 30 luglio.
italianparliament committee-sessions list --committee-uri http://dati.senato.it/commissione/0-1 \
--chamber senato --date-from 2026-07-25 --date-to 2026-08-01
Limiti noti del LOD, verificati: il relatore di un Atto del
Governo non c’è, né alla Camera né al Senato — va letto dal
resoconto o dalla scheda dell’atto. E le email dei deputati non
esistono: la Camera non le pubblica né nel LOD né nella scheda
personale (verificato anche aprendo la scheda con un browser). Il Senato
invece pubblica nome.cognome@senato.it nella scheda del
senatore.
L’elenco destinatari-camera-ag418.csv nasce così. Nota
all_varchar=true: senza, le colonne di date vuote fanno
fallire la conversione a INT64.
duckdb -c "
COPY (
WITH m AS (
SELECT member_uri, member_name, role, 'I Affari costituzionali' AS commissione
FROM read_csv_auto('camera-I-membri.csv', header=true, all_varchar=true) WHERE end_date IS NULL
UNION ALL
SELECT member_uri, member_name, role, 'II Giustizia'
FROM read_csv_auto('camera-II-membri.csv', header=true, all_varchar=true) WHERE end_date IS NULL
),
g AS (SELECT deputy_uri, group_label,
row_number() OVER (PARTITION BY deputy_uri ORDER BY start_date DESC) rn
FROM read_csv_auto('camera-gruppi.csv', header=true, all_varchar=true) WHERE end_date IS NULL),
d AS (SELECT uri, election_label, html_url
FROM read_csv_auto('camera-deputati.csv', header=true, all_varchar=true))
SELECT m.commissione, m.member_name AS deputato, m.role AS ruolo_commissione,
g.group_label AS gruppo,
regexp_extract(d.election_label, 'circoscrizione ([A-ZÀ-Ù0-9 ''\-]+?) nelle', 1) AS circoscrizione,
d.html_url AS scheda
FROM m LEFT JOIN g ON g.deputy_uri = m.member_uri AND g.rn = 1
LEFT JOIN d ON d.uri = m.member_uri
) TO 'destinatari-camera-ag418.csv' (HEADER, DELIMITER ',');"
Playbook completo del display:
/mnt/c/varie/msi/wsl/display-x410.md. In sintesi, in rete
NAT DISPLAY deve puntare al gateway Windows, non a
127.0.0.1.
GW=$(ip route | grep default | awk '{print $3; exit}')
for ip in 127.0.0.1 "$GW"; do
timeout 2 bash -c "echo > /dev/tcp/$ip/6000" 2>/dev/null && { export DISPLAY=$ip:0.0; break; }
done
echo "$DISPLAY" # es. 172.19.0.1:0.0
agent-browser close --all
agent-browser open "https://www.senato.it/leggi-e-documenti/attivita-non-legislative/procedure?documentoId=56098" \
--headed --profile ~/.agent-browser-profiles/senato \
--args "--enable-unsafe-swiftshader,--ignore-gpu-blocklist"
agent-browser read > pagina.txt
close --all va sempre per primo: se il daemon è già
vivo, --headed e --profile vengono ignorati e
riparte headless.
Per estrarre i link dei resoconti dalla pagina di trattazione:
agent-browser eval "Array.from(document.querySelectorAll('a')) \
.filter(a => /Resoconto/i.test(a.textContent)) \
.map(a => a.textContent.trim() + ' || ' + a.href).join('\n')"
I resoconti hanno una struttura a parti: la pagina base mostra solo
l’indice, il testo sta in &part=doc_dc e gli allegati —
dove si trova il testo del parere approvato — in
&part=doc_dc-allegato_a.
https://www.senato.it/show-doc?leg=19&tipodoc=SommComm&id=1518018&idoggetto=0 # indice
https://www.senato.it/show-doc?leg=19&tipodoc=SommComm&id=1518018&idoggetto=0&part=doc_dc # resoconto
https://www.senato.it/show-doc?leg=19&tipodoc=SommComm&id=1518018&idoggetto=0&part=doc_dc-allegato_a # parere
La scheda di un Atto del Governo alla Camera ha lo stesso numero del Senato e contiene assegnazioni, termini, relatori, sedute, audizioni e memorie depositate:
curl -sL -A "Mozilla/5.0" "https://www.camera.it/leg19/682?atto=418&idLegislatura=19&tab=&tipoAtto=atto" -o cam418.html
Estrazione dei link ai PDF delle memorie:
python3 -c "
import re, html
t = open('cam418.html', encoding='utf-8', errors='ignore').read()
for m in re.finditer(r'<a[^>]*href=\"([^\"]+)\"[^>]*>(.*?)</a>', t, re.S):
txt = html.unescape(re.sub(r'<[^>]+>', '', m.group(2))).strip()
if 'Memoria' in txt: print(txt, '||', m.group(1))
"
liteparse parse memoria.pdf --format markdown --image-mode off -o memoria.md
In alternativa
kreuzberg extract --content-format markdown <file>, e
markitdown come ripiego.
Brave, con la chiave già in ambiente. È servita per trovare il numero corretto del provvedimento del Garante, che sul sito non è indicizzato in modo evidente:
curl -s -H "X-Subscription-Token: $BRAVE_API_KEY" -H "Accept: application/json" \
"https://api.search.brave.com/res/v1/web/search?q=<query urlencoded>&count=10&country=it&search_lang=it" \
| python3 -c "import sys,json;[print('-',r['title'],'\n ',r['url']) for r in json.load(sys.stdin)['web']['results']]"
Exa via MCP funziona ma restituisce risposte molto grandi, che vanno lette da file invece che a schermo.
Il notebook di lavoro è «Protezione dei dati personali in ambito
penale: Direttiva 2016/680», id
2d0fadcc-63ba-4ae4-ba16-cb6dca965dda.
export DISPLAY=172.19.0.1:0.0 # il login apre un browser: senza X410 fallisce
notebooklm login # va lanciato in un terminale interattivo: chiede INVIO
notebooklm auth check --test --json # deve dare status ok E token_fetch true
notebooklm list --json
notebooklm source list -n <notebook-id> --json
notebooklm source add ./file.pdf -n <notebook-id> --json
notebooklm source delete <source-id> -n <notebook-id> -y
notebooklm ask "domanda" -n <notebook-id> -s <source-id> -s <source-id>
Tre cose imparate a spese nostre:
auth check dà cookie presenti ma
token_fetch: false, il problema è la versione della
CLI, non il login: con la 0.3.4 l’autenticazione falliva
comunque, uv tool upgrade notebooklm-py alla 0.7.3 l’ha
risolta senza rifare nulla;documenti.camera.it
non vengono letti da NotebookLM: i bollettini vanno
scaricati e caricati come file di testo. I tentativi falliti restano nel
notebook come fonti in stato error e vanno cancellati a
mano;Le scadenze del procedimento — parere della Camera, adozione
definitiva entro il 10 ottobre 2026 — si annotano con gwsb
sul calendario gmail.com, evento a orario, fuso
Europe/Rome.