Panoramica
Il linguaggio di scripting di JuliuS è un JavaScript esteso con direttive speciali. Ogni script è un file di testo (.js) composto da due tipi di istruzioni che coesistono:
- Direttive JuliuS — righe che iniziano con
//#*#, interpretate dal motore Delphi per controllare browser, timing, OS e flusso. - Blocchi JavaScript — codice JS puro racchiuso tra
//#*#SNIPPET=BEGINe//#*#SNIPPET=END, eseguito nel browser Chromium.
//#*# sembrano commenti JS ma vengono intercettate dall'engine prima di qualsiasi valutazione JavaScript, garantendo piena compatibilità con editor JS standard.Struttura di uno script
Intestazione / Commento
Titolo, descrizione, nome della compagnia/target.
GLOBALV — Dichiarazione variabili
Blocco GLOBALV=BEGIN / END con tutte le variabili di input.
Configurazione iniziale
SCREEN_SIZE, WAIT, TARGET_FRAME=MAIN.
Navigazione verso l'URL target
URL_GOTO seguito da WAIT per il caricamento.
Interazione con la pagina
Sequenza di SNIPPET, MOUSE_CLICK, WRITETO, IF/ELSE/ENDIF, WAIT.
Estrazione del risultato
Definizione della funzione JS di estrazione, EVALJS, CAPTURE_SCREENSHOT.
Ciclo di esecuzione
L'engine legge lo script riga per riga in un thread separato. Per ogni riga:
- Se inizia con
//#*#→ viene interpretata come direttiva JuliuS. - Se è compresa tra
SNIPPET=BEGINeSNIPPET=END→ viene accumulata e inviata al browser come JavaScript. - Se inizia con
/*→ l'engine salta tutte le righe fino al corrispondente*/. - Altrimenti → la riga viene ignorata dall'engine.
SNIPPET non viene eseguito nel browser. Tutto il JS da eseguire va obbligatoriamente dentro un blocco SNIPPET.GLOBALV — Variabili globali
datiGLOBALV=BEGIN e GLOBALV=END viene caricato nella lista interna GlobalV di JuliuS e può essere iniettato nel browser con GLOBALV=INJECT. Ogni riga deve essere una dichiarazione JavaScript valida var nome="valore";. I valori vengono estratti dall'engine per l'interpolazione con la sintassi {{{NOME}}}.GLOBALV=INJECT
javascriptGlobalV nel contesto JavaScript del browser. Dopo l'inject, tutte le variabili del blocco GLOBALV sono disponibili come variabili JS nella pagina corrente e possono essere usate nei successivi blocchi SNIPPET. Poiché ogni navigazione azzera il contesto JS, è necessario re-iniettare dopo ogni cambio pagina.GLOBALV=INJECT dopo ogni navigazione verso una nuova pagina.Interpolazione {{{VAR}}}
datiLe variabili definite in GLOBALV possono essere interpolate nei parametri delle direttive JuliuS usando {{{NOME_VARIABILE}}}. L'engine sostituisce il placeholder con il valore prima di eseguire il comando. I nomi sono case-insensitive.
HTTP_GET / HTTP_POST
httpVAR, salva la risposta testuale in GLOBALV. I parametri supportano l'interpolazione {{{VAR}}}, quindi URL, body e header possono usare valori dichiarati o prodotti durante l'esecuzione.VAR, JuliuS inietta subito la variabile anche nel browser corrente. Uno SNIPPET immediatamente successivo puo quindi leggere la response senza aspettare un GLOBALV=INJECT. Dopo una navigazione serve comunque re-iniettare le variabili.Parametri
| Parametro | Tipo | Descrizione |
|---|---|---|
| URL | string | Endpoint da chiamare. Obbligatorio. |
| VAR | string | Nome della variabile GLOBALV in cui salvare la risposta. |
| BODY | string | Payload per HTTP_POST. Con HTTP_GET viene accodato alla URL come query string (?BODY o &BODY se la URL ha gia parametri). Supporta interpolazione. |
| CONTENTTYPE | string | Content-Type del POST, ad esempio application/json o application/x-www-form-urlencoded. |
| TIMEOUTMS | integer | Timeout connessione/risposta in millisecondi. Default: 30000. |
| HEADER_Nome | string | Aggiunge un header HTTP. Gli underscore nel nome vengono convertiti in trattini, ad esempio HEADER_X_API_KEY diventa X-API-KEY. |
& trova una chiave nota, quindi query string e body form-urlencoded possono contenere &. CONTENTTYPE ha un alias equivalente CONTENT_TYPE.FIELD, ONCE, CLEAR, DELETE, DELETEAFTERUPLOAD e FORM_*. Una stringa letterale come &FIELD= o &DELETE= dentro un BODY o una URL di HTTP_GET/HTTP_POST verrebbe interpretata come inizio di un nuovo parametro: evitare questi token nei valori oppure codificarli.{{{nome}}} vengono risolti prima dalle variabili GLOBALV; se non vengono trovati, JuliuS prova a valutarli nel contesto JavaScript del browser con EvalJS. Questo permette di usare nel BODY, nell'URL o negli header anche valori calcolati in uno SNIPPET precedente.DOWNLOAD_UPLOAD ⚠️ non attiva
httpExecuteDownloadUploadCommand e tutta la logica di download/upload sono implementate in uFrmScript.pas/uMainBrowser.pas, ma il ciclo principale di esecuzione script (ExecuteScript) non ha alcun ramo StartsWith('//#*#DOWNLOAD_UPLOAD='). Inserire questa direttiva in uno script oggi non produce alcun effetto (no-op silenzioso). La sezione è mantenuta come riferimento per quando il collegamento verrà aggiunto: non usarla in script di produzione fino ad allora.POST multipart/form-data all'endpoint indicato.Parametri
| Parametro | Tipo | Descrizione |
|---|---|---|
| URL | string | Endpoint di upload. Obbligatorio. |
| FIELD | string | Nome del campo multipart che contiene il file. Default: file. |
| VAR | string | Nome della variabile GLOBALV in cui salvare la response testuale dell'upload. |
| TIMEOUTMS | integer | Timeout connessione/risposta in millisecondi. Default: 120000. |
| HEADER_Nome | string | Header HTTP aggiuntivo. Gli underscore nel nome vengono convertiti in trattini. |
| FORM_Nome | string | Campo form multipart aggiuntivo, oltre al file. Supporta interpolazione. |
| ONCE | boolean | Se true, la configurazione vale solo per il prossimo download. Default: true. |
| DELETE / DELETEAFTERUPLOAD | boolean | Se true, elimina il file locale dopo upload riuscito. Default: false. |
| CLEAR | boolean | Se true, rimuove la configurazione corrente senza attendere un download. |
URL_GOTO
navigazioneWAIT subito dopo per attendere il caricamento completo della pagina prima di interagire con il DOM.WAIT
controllo flussoBACK
navigazioneWAIT e un GLOBALV=INJECT per ripristinare il contesto JS.SCREEN_SIZE
navigazioneMOUSE_CLICK e OS_BROWSER_CLICK devono essere calibrate sulla risoluzione impostata con questo comando.MOUSE_CLICK
interazione CEFpointer-events:none, scrollbar native, dialog Windows) usare OS_BROWSER_CLICK.WRITETO
interazione CEF& e racchiusi tra virgolette doppie. Supporta interpolazione {{{VAR}}} e tasti speciali {{TASTO}}.Parametri
| Parametro | Tipo | Descrizione |
|---|---|---|
| ELEMENTID | string | ID HTML dell'elemento su cui mettere il focus. Usare none per saltare il focus. |
| FRAMENAME | string | Nome del frame/iframe target. Se omesso usa il frame con focus corrente. |
| TEXT | string | Testo da digitare. Supporta {{{VAR}}} e {{KEY}}. |
| CHAR_INT_MS | integer | Intervallo ms tra un carattere e l'altro (default: 200). |
| CHAR_INT_RANDOM | S / N | Se S, ogni intervallo tra due caratteri diventa un valore casuale uniforme tra 0 e CHAR_INT_MS-1 (non una variazione attorno al valore configurato). |
ELEMENTID supporta il fallback su valutazione JS (come HTTP_GET/HTTP_POST); il parametro TEXT supporta solo la sostituzione diretta delle variabili GLOBALV — un'espressione JS scritta dentro {{{...}}} nel TEXT non viene valutata a runtime.Tasti speciali
interazione CEFAll'interno del parametro TEXT del comando WRITETO:
{{ARROW_RIGTH}} (typo di "RIGHT"), mantenuto per compatibilità con script esistenti — negli script nuovi usare {{ARROW_RIGHT}}. {{SELECT_ALL}} è gestito a un livello diverso rispetto agli altri placeholder: divide il testo sul marker e invia la combinazione Ctrl+A in quel punto, direttamente dentro la routine di digitazione. Qualsiasi altro carattere non elencato (inclusi accentati e simboli) viene digitato come carattere letterale.SNIPPET
javascriptSNIPPET=BEGIN e SNIPPET=END viene eseguito nel contesto JavaScript del browser Chromium. È il meccanismo principale per interagire con il DOM. L'opzione NOFRAME forza l'esecuzione nel frame principale (window) invece del frame con focus corrente.SNIPPET=BEGIN deve avere il suo SNIPPET=END.EVALJS
javascript?operation=getresult. Pensato per chiamare funzioni di estrazione già definite in un SNIPPET precedente.TARGET_FRAME
navigazioneMAIN seleziona il frame principale; POPUP seleziona una finestra popup figlia identificata dall'URL nella riga successiva.| Valore | Descrizione |
|---|---|
| MAIN | Frame principale della finestra browser corrente. |
| POPUP | Popup figlio. Deve essere seguito da //#*#TARGET_URL=<url>. |
Regole di matching di TARGET_URL
| Valore | Comportamento |
|---|---|
* o vuoto | Usa l'ultimo popup attivo (nessun match per URL). |
| URL esatto | Cerca un popup la cui URL corrisponde esattamente. |
| URL parziale | Se non trova corrispondenza esatta, cerca un popup la cui URL contiene il valore indicato (match a sottostringa). |
IF / ELSE / ENDIF
controllo flussoIF= viene valutata nel browser tramite EvalJS: se il risultato è truthy il blocco IF viene eseguito e il blocco ELSE saltato; se è falsy il blocco IF viene saltato e il blocco ELSE (opzionale) eseguito. Il blocco ELSE è opzionale. Gli IF possono essere annidati: l'engine gestisce correttamente la profondità di annidamento.Valori considerati falsy
Stringa vuota "", "false", "0", "null", "undefined". Qualsiasi altro valore è considerato truthy.
EvalJS nel thread principale. Le variabili iniettate con GLOBALV=INJECT sono disponibili nell'espressione. Il risultato della valutazione viene scritto nel log di JuliuS per facilitare il debug (IF [expr] = valore → true/false).PAUSE
controllo flusso?operation=start). Utile per interventi manuali (es. risoluzione captcha, login manuale) in punti critici del flusso. Spesso usato in combinazione con IF per sospendere solo in caso di condizioni anomale.'go' via WSS, lo script si sblocca e riparte automaticamente. Timeout di sicurezza: se non arriva attività remota per più di 120s, JuliuS esce comunque dalla pausa.CAPTURE_SCREENSHOT
output CEFSettings.Data.screenShotPath. Il nome file è costruito automaticamente come ExcelLogLineNameBase_N.jpg. Il percorso viene aggiunto alla screenShotList del risultato operazione, recuperabile via API. Se al momento della cattura è attivo TARGET_FRAME=POPUP, viene salvata la pagina completa del popup corrente invece della finestra browser principale.OS_SCREENSHOT
output OSscreenShotList del risultato operazione.| Variante | Descrizione |
|---|---|
//#*#OS_SCREENSHOT | Nome file automatico: ExcelLogLineNameBase_OS_N.jpg |
//#*#OS_SCREENSHOT=nomeFile | Nome file personalizzato: nomeFile.jpg |
CAPTURE_SCREENSHOT cattura solo il pannello CEF. OS_SCREENSHOT cattura l'intero desktop Windows incluse finestre native, taskbar e popup di sistema.Funzione di risultato
javascriptPer restituire un risultato recuperabile via API, definire una funzione JS in un blocco SNIPPET e richiamarla con EVALJS. Per convenzione si chiama preventivo(), ma è possibile usare qualsiasi nome.
operation=getresult / getresult=<nome> non è la stringa grezza restituita dalla funzione, ma un oggetto JSON con almeno i campi OperationId, rawResult (il valore ritornato dalla funzione), StartedAt e screenShotList (elenco degli screenshot catturati durante l'esecuzione). Il client deve leggere rawResult dal JSON, non trattare l'intera risposta come testo semplice.operation= (controllo script, DOM/ispezione pagina, screenshot, input OS, log di rete/API) non correlate al linguaggio di scripting — vedi API HTTP Reference.OS_MOUSE_MOVE
OS — mouseOS_MOUSE_CLICK
OS — mouseOS_MOUSE_MOVE. Agisce a livello SO e può interagire con qualsiasi finestra visibile sul desktop.OS_MOUSE_RCLICK
OS — mouseOS_MOUSE_MOVE_CLICK
OS — mouseOS_MOUSE_MOVE e OS_MOUSE_CLICK in una sola direttiva usando coordinate assolute di schermo. Le coordinate dipendono dalla posizione della finestra JuliuS sul desktop: se la finestra viene spostata, le coordinate devono essere ricalcolate. Per click indipendenti dalla posizione della finestra, preferire OS_BROWSER_CLICK.OS_MOUSE_DOUBLE_CLICK
OS — mouseOS_MOUSE_MOVE_PATH
OS — mousex,y,delay separate da ;. delay è il tempo in millisecondi da attendere prima di muoversi verso quel punto (clampato a un massimo di 400ms per segmento).OS_BROWSER_CLICK
OS — mouseMOUSE_CLICK e degli snapshot. Internamente, JuliuS converte le coordinate browser in coordinate assolute di schermo tramite ClickOnBrowserRelative, quindi il click funziona correttamente indipendentemente da dove è posizionata la finestra JuliuS sul desktop e dal fattore di scala DPI. È la scelta più robusta quando si vuole un click OS su un elemento del browser.Quando usarlo rispetto alle alternative
| Direttiva | Tipo click | Coordinate | Quando usarla |
|---|---|---|---|
| MOUSE_CLICK | CEF interno | Relative browser | Caso generale: elementi DOM standard |
| OS_MOUSE_MOVE_CLICK | SO | Assolute schermo | Click su finestre esterne al browser |
| OS_BROWSER_CLICK | SO | Relative browser | Elementi che non rispondono al CEF, scrollbar, dropdown nativi, pointer-events:none |
OS_BROWSER_INFO
OS — debugOS_MOUSE_MOVE e OS_MOUSE_MOVE_CLICK.OS_KEY_PRESS
OS — tastieraWRITETO che scrive nel browser CEF, questo comando agisce a livello SO e funziona su qualsiasi finestra attiva: dialog nativi Windows, form non web, applicazioni desktop.| Keycode | Tasto | Keycode | Tasto |
|---|---|---|---|
| 13 | ENTER | 27 | ESC |
| 9 | TAB | 32 | SPAZIO |
| 8 | BACKSPACE | 46 | DELETE |
| 37 | ← LEFT | 38 | ↑ UP |
| 39 | → RIGHT | 40 | ↓ DOWN |
| 112–123 | F1–F12 | 65–90 | A–Z |
OS_KEY
OS — tastieraOS_KEY_PRESS: accetta il nome del tasto invece del keycode numerico. Agisce a livello sistema operativo sulla finestra attiva. I nomi non riconosciuti vengono loggati e ignorati senza interrompere lo script.| Valore | Tasto | Valore | Tasto |
|---|---|---|---|
| enter | ENTER | esc / escape | ESC |
| tab | TAB | backspace | BACKSPACE |
| space | SPAZIO | arrow_up | ↑ |
| arrow_down | ↓ | arrow_left | ← |
| arrow_right | → |
OS_KEY_COMBO
OS — tastierakeybd_event. La sintassi è modificatore+tasto in minuscolo. Disponibile solo su Windows: su altre piattaforme il comando viene loggato come non implementato e ignorato senza interrompere lo script.| Campo | Valori accettati |
|---|---|
| modifier | ctrl, shift, alt |
| key | Lettera singola (a–z), oppure: f4–f12, tab, enter, esc, del, home, end, pageup, pagedown |
RNDWAIT
controllo flusso[N div 2 .. N]. Da usare al posto di WAIT fissi sulle pause lunghe (submit form, caricamento pagina) per ridurre il rischio di rilevamento anti-bot.RNDWAIT sulle pause lunghe e mantieni WAIT=1 per le sincronizzazioni brevi dove la variabilità non serve.CAPTCHA_Y
controllo flussoSettings.Data.captchaScrollCoordComma).Captcha Interceptor & Solver Bridge
funzionalità applicativa//#*#: è un sistema dell'applicazione, configurato in Settings, documentato qui come contesto perché influenza il comportamento a runtime di PAUSE e CAPTCHA_Y.Captcha Interceptor + operatore remoto via WSS
Due toggle indipendenti in Settings: AI Resolver (abilita il rilevamento automatico dei captcha) e WSS (abilita la connessione al server WebSocket remoto, indirizzo configurabile). Quando il frame con focus corrisponde a un captcha (esclusi i badge invisibili), JuliuS centra la view sulla coordinata di CAPTCHA_Y e invia screenshot live al resolver remoto via WSS. Un operatore/resolver connesso può cliccare e scrollare da remoto sul browser JuliuS; quando ha risolto, invia un messaggio 'go' che sblocca automaticamente un eventuale PAUSE in corso e fa ripartire lo script. Se non arriva attività remota per più di 120s, JuliuS esce comunque dalla pausa.
Solver Bridge — API richiamabile da SNIPPET
A differenza del canale sopra, questa è un'API JavaScript utilizzabile direttamente dentro un blocco SNIPPET, indipendente dal toggle "AI Resolver":
La risposta arriva in modo asincrono in window.__juliusSolver.responses[reqId] = {success, answer, error} (oppure via callback registrata in window.__juliusSolver.callbacks[reqId]).
qwen3-vl:8b, endpoint OCR) invece che al resolver remoto via WSS. Verificare lo stato del codice prima di fare affidamento su questa via per script di produzione.RESTART_CHROMIUM
sessioneabout:blank, Network.clearBrowserCache, Network.clearBrowserCookies, Storage.clearDataForOrigin (localStorage/sessionStorage/IndexedDB), riapplica le preferenze Chromium e torna su about:blank. Attende automaticamente ~3s di reinizializzazione. Esposto anche come tool MCP julius_restart_chromium().DELETE_CHROMIUM_CACHE
sessioneRESTART_CHROMIUM) e poi cancella fisicamente la directory cache su disco (GlobalCEFApp.RootCache). Attende automaticamente ~4s (più di RESTART_CHROMIUM per via dell'I/O filesystem). Esposto anche come tool MCP julius_delete_chromium_cache().| RESTART_CHROMIUM | DELETE_CHROMIUM_CACHE | |
|---|---|---|
| Tipo reset | In-memory (DevTools) | In-memory + filesystem |
| Velocità | ~3s | ~5s (I/O disco) |
| Cancella file su disco | No | Sì |
| Quando usare | Reset tra un preventivo e l'altro | Cache corrotta, reset completo pre-sessione |
RESTART_CHROMIUM non è sufficiente (cache corrotta, sessioni persistenti problematiche, primo avvio di una nuova sessione di lavoro).Macro Recorder
registrazioneJuliuS può generare lo script automaticamente osservando le interazioni reali dell'utente sul browser embedded. Si attiva con il ToggleSwitch REC nella finestra Script. È il modo più veloce per ottenere una bozza funzionante da rifinire.
Attivazione (REC → ON)
Viene iniettato un listener JS nel frame principale, negli iframe nominati e nei popup TChildForm. Si auto-protegge dalla doppia installazione (window.__jrInstalled) e resta inerte finché window.__jrActive non è true.
Cattura eventi
Intercetta in capture phase gli eventi click e change, costruisce un selettore CSS stabile (#id o cssPath con :nth-of-type/[name]) e invia un payload JSON via myextension.sendresulttobrowser(json, 'jsRecordEvent').
Generazione script
TfrmScript.RecordEvent riceve il JSON e accoda nell'editor le direttive JuliuS corrispondenti, parametrizzando i valori in GLOBALV.
Disattivazione (REC → OFF)
Imposta window.__jrActive=false su tutti i frame; il listener resta installato ma inerte.
Modalità "Uman"
Un secondo ToggleSwitch (separato da REC) abilita, quando REC è attivo, anche la registrazione del movimento reale del mouse a livello di sistema operativo:
- Il movimento viene campionato da un hook OS globale già installato, con un throttling di circa 1 campione ogni 40ms e uno scarto dei movimenti inferiori a 6px.
- I punti vengono bufferizzati (fino a 50) e, appena prima del prossimo click o input registrato, vengono emessi in un'unica riga
//#*#OS_MOUSE_MOVE_PATH=...(vedi sezione dedicata). - Il ridimensionamento del pannello browser durante la registrazione genera anche righe
//#*#SCREEN_SIZE=W,H, ma solo se l'header dello script è già stato generato.
Mappatura eventi → direttive generate
| Evento utente | Output nello script |
|---|---|
| Primo evento, editor vuoto | Header completo: GLOBALV=BEGIN/END, SCREEN_SIZE=1024,768, WAIT=1, TARGET_FRAME=MAIN, URL_GOTO=<pagina>, WAIT=8, GLOBALV=INJECT |
| Primo evento, editor non vuoto | Garantisce un blocco GLOBALV e accoda le azioni in append |
| Attesa tra due azioni | //#*#WAIT=N proporzionale ai secondi reali (parte intera, emesso solo se ≥1s, clamp 1–20s) |
| Cambio URL | //#*#GLOBALV=INJECT |
| Cambio frame / popup | //#*#TARGET_FRAME=<frame>; per i popup TARGET_FRAME=POPUP + TARGET_URL=* |
| Ridimensionamento finestra (modalità Uman) | //#*#SCREEN_SIZE=W,H |
| Movimento mouse reale (modalità Uman) | //#*#OS_MOUSE_MOVE_PATH=x1,y1,d1;x2,y2,d2;..., emesso subito prima del prossimo click/input |
Input su campo con id | Variabile in GLOBALV + //#*#WRITETO="ELEMENTID=<id>"&"TEXT={{{var}}}"&"CHAR_INT_MS=60" (intervallo fisso a 60ms) |
Input su campo senza id | Variabile + SNIPPET con querySelector(sel).value=var + eventi input/change |
| Click | Commento // [REC] click … con coordinate alternative //#*#MOUSE_CLICK=x,y + SNIPPET con scrollIntoView() + .click() + WAIT=1 |
GLOBALV (nome derivato da id/name: caratteri non alfanumerici → _, prefisso v_ se il nome inizia con una cifra, duplicati resi univoci con suffisso _N). Ri-digitazioni sullo stesso campo aggiornano la stessa variabile invece di crearne una nuova.change semplici. Rifinisci sostituendo con i pattern dropdown a cascata, aggiungi gestione cookie/captcha e la funzione preventivo() di estrazione risultato.Best practice
Gestione banner cookie
Re-inject variabili dopo navigazione
Compilazione dropdown con jQuery
Esecuzione condizionale con IF
Usare IF per gestire variazioni di pagina o errori senza interrompere il flusso principale:
Click OS con coordinate relative al browser
Preferire OS_BROWSER_CLICK a OS_MOUSE_MOVE_CLICK per non dover ricalcolare le coordinate assolute se la finestra viene spostata:
Commenti
controllo flussoJuliuS supporta entrambe le sintassi di commento JavaScript. I blocchi
/* ... */sono utili per disabilitare temporaneamente intere sezioni, incluse direttive JuliuS.