Wget - L'arte della copia
di Paris Cristiano
Impariamo ad utilizzare al meglio wget, un'utility potente e altamente configurabile per scaricare file da web e ftp
Sin dai tempi in cui il world wide web muoveva i suoi primi passi, gli utenti hanno sentito l'esigenza di poter consultare a modem spento i documenti che trovavano in linea; a quei tempi, quando i modem a malapena raggiungevano i 9600 bps, scaricare il sito preferito, per poi scoprire che non era cambiato dall'ultimo download, non era proprio la cosa più divertente.
Anche oggi che abbiamo infranto tutte le barriere e siamo arrivati a velocità di tutto rispetto, il discorso non è cambiato: maggiore è la banda a disposizione, più aumentano i bit che i web master riescono a mettere in linea per singola pagina. Insomma, cambia il periodo storico, aumentano le prestazioni della rete, ma il problema rimane, lanciando alla ribalta quei programmi che consentono di visualizzare offline i siti web, i cosiddetti offline browser e i programmi per il mirroring.
Fra i vari programmi nati per scaricare dalla rete interi siti, si distingue sicuramente wget: è potente, versatile, multipiattaforma e freeware. L'unico inconveniente sta nella difficoltà iniziale nel "domarlo": la quantità incredibile di opzioni, unite all'interfaccia a linea di comando, ne fanno uno strumento di utilizzo non immediato.
Tanti piccoli programmi
Se siete abituati a programmi simili sotto Windows, sappiate che wget è estremamente diverso, in quanto non utilizza alcuna interfaccia grafica: tutto si risolve in un file di configurazione e un paio di argomenti sulla linea di comando. In tal senso, wget è conforme a tutte le migliori specifiche che definiscono un buon programma Unix, come ad esempio la possibilità di utilizzare le pipe e di processare la linea di comando tramite "getopt". Soffermiamoci un attimo su queste due caratteristiche: spesso chi proviene dal mondo Windows prova un senso di impotenza o di insofferenza verso quei programmi che fanno uso intensivo della riga di comando, che risultano poco intuitivi e difficili da gestire. Questo, purtroppo, è una eredità della impostazione Microsoft, che ha abituato gli utenti ad applicazioni "all-in-one", nelle quali tutto si risolve in pochi clic del mouse, senza che vi sia una reale comprensione del funzionamento del programma. Con wget, invece, siamo di fronte a più programmi che cooperano per raggiungere una serie di risultati che vanno al di la del semplice mirroring di un sito web, ma questo è possibile solo grazie al supporto del sistema operativo, grazie anche ai meccanismi di pipe e di scripting che esso mette a disposizione degli utenti.
Vedremo, quindi, come sia possibile usare wget per svolgere compiti complessi, ben oltre gli scopi per il quale è stato creato, ovvero scaricare file in modalità automatica, utilizzando i protocolli http ed ftp.
ALBERO DIRECTORY DI UN SERVER WEB LINUX
Alberi e grafi
Per capire come funziona questo programma occorre prima capire come è strutturato il www. Schematizzando, sparsi nel mondo troviamo alcuni computer nei quali sono immagazzinate informazioni di cui si può prendere visione tramite internet; tali computer sono detti "server" e il modo con il quale essi immagazzinano l'informazione è tipicamente lo stesso utilizzato sul pc di casa.
Quindi, anche sul "server" sarà presente un albero delle directory, che comincia dalla radice '/' e che si estende in sottodirectory: questo tipo di struttura rappresenta il livello "fisico" con il quale i dati vengono mantenuti sul server.
Tuttavia, la peculiarità del www è quella di essere basato su particolari tipi di documenti che sfruttano il formato html per realizzare i famosi collegamenti ipertestuali, vero punto centrale di tutta la tecnologia web. Riprendendo la nostra struttura ad albero, si vengono ad aggiungere rami che collegano i livelli differenti o nodi su uno stesso livello e che rappresentano proprio i link ipertestuali; il nostro albero si trasforma dunque in una nuova struttura che gli informatici chiamano "grafo". In realtà, se avete un minimo di conoscenza Linux, saprete bene che i collegamenti messi a disposizione dell'utente dal virtual file system offrono la possibilità di ricreare una struttura a grafo nell'albero delle directory tradizionale presente sul disco rigido. In ogni caso, il grafo di un sito Internet ne rappresenta la sua struttura "logica", che permette all'utente di navigare in maniera più comoda ed intuitiva.
Fra questi due livelli, fisico e logico, interviene wget, il cui compito è quello di ricreare sul vostro disco rigido la struttura ad albero (livello fisico) di un sito partendo dalla sua struttura a grafo (livello logico), sfruttando proprio i collegamenti ipertestuali presenti in un documento html.
A complicare le cose c'è anche il fatto che tali link sono rappresentati da oggetti ben definiti, chiamati url (uniform resource locator), che consentono di definire collegamenti ad altri documenti in siti ospitati da altri server. A questo punto capirete perché si parli di web, ovvero di "ragnatela" quando ci si riferisce al web e di quanto debba essere flessibile e complesso un programma come wget, che proprio con il web ha a che fare.
Esempi elementari
Per capire meglio come funziona questo programma, facciamo qualche esempio pratico. Supponiamo che vogliate scaricare un documento consigliatovi da un vostro amico e che sapete conterrà delle immagini. Immaginiamo quindi che l'url sia in "www.funnystuff.com" e che vogliate mettere il suo contenuto in "~/mydocs"; date allora il seguente comando:
wget -S -p ~/mydocs www.funnystuff.com
wget risponderà con svariate informazioni sul documento che si sta scaricando (opzione -S), salvando i dati nella directory specificata dall'opzione -p.
Alla fine download vi ritroverete con il documento "doc10.html" all'interno di "~/mydocs", che però non conterrà alcuna immagine, per scaricare tutto il contenuto della pagina, è necessario abilitare la ricorsione, ovvero la capacità di seguire i collegamenti e la struttura delle directory, scaricando tutti gli elementi di un documento html. Modifichiamo quindi la precedente linea di comando, e otterremo:
wget -Sr -p ~/mydocs www.funnystuff.com
Ora ci siamo. Alla fine del download troverete all'interno di "~/mydocs" una directory "www.funnystuff.com" che conterrà tutti i file scaricati, con l'albero delle directory nel quali erano originariamente contenute.
A questo punto, però, sorge un problema: wget potrebbe impiegare un tempo estremamente lungo per completare il download della pagina, dato che deve seguire tutti i collegamenti che si presentano nella pagine che abbiamo indicato, nonché tutti i link contenuti nei documenti html che si troverà a scaricare. Abbiamo dato inizio così ad una catena che può portare sul nostro disco un numero enorme di file: se, ad esempio, ogni pagina contiene 5 collegamenti a file generici (altre pagine, immagini, testo ecc.), con le impostazioni di default wget sarà costretto a scaricare ben 3906 file che, supponendo una lunghezza media di 5k per file, corrispondono a circa 18Mb. È quindi necessario rendere ancora più complessa la nostra linea di comando, imponendo delle limitazioni al numero di file da scaricare.
Limitiamoci
Prima di proseguire, affrontando l'argomento limitazioni, conviene chiarire bene il significato dei termini "livello" e "profondità". Facendo riferimento alla prima figura, potete immaginare l'url come un indicatore che si riferisce ad un nodo specifico dell'albero. Adesso guardiamo l'immagine in questra pagina, dove al centro è
stato messo tale nodo: da quest'ultimo dipartono alcuni rami che rappresentano collegamenti ad altrettanti nodi dell'albero, e che rappresentano il "vicinato".
I nodi del vicinato sono caratterizzati dal fatto che sono tutti raggiungibili da quello centrale attraversando un solo ramo e per questo si dice che si trovano nel "primo livello". Analogamente, tutti quelli raggiungibili attraversando due rami, si trovano nel "secondo livello" e così via.
La "profondità" di attraversamento è il numero massimo di livelli che si possono attraversare per raggiungere un nodo periferico a partire da un nodo centrale.
Il concetto di profondità di livello è centrale in wget, perché rappresenta il fattore primario in grado di limitare l'attraversamento di un sito. Facciamo un esempio: se aggiungiamo alla precedente stringa il valore -l 1
wget -Sr -l 1 www.funnystuff.com
non scaricheremo più solo le immagini collegate alla pagina che intendiamo prelevare, ma anche tutti gli oggetti che si trovano nel primo livello rispetto a file doc10.html e che sono da questo "linkati".
Ma davvero vogliamo scaricare tutto? Potremmo anche incorrere in file inutili, come contatori, file di database o altri documenti, di cui non ci interessa nulla e che occupano solo banda e allungano i tempo di download. Per evitare un tale spreco, possiamo fornire a wget una "accept list", o al contrario una "reject list", nella quale possiamo specificare le estensioni dei file che intendiamo scaricare. Se, ad esempio, volessimo prelevare tutti i file grafici in formato gif e jpg, collegati in primo livello con il documento doc10.html, e nient'altro, potremmo scrivere:
wget -Sr -l 1 -A gif,jpg www.funnystuff.com
Notate come questo elimini anche l'eventuale contatore, che tipicamente non è rappresentato da un'immagine con suffisso gif o jpg, ma da uno script cgi. Nel caso mirassimo ad eliminare esclusivamente il contatore, dovremmo utilizzare delle wildcard (* o ?) che interessino la directory "/cgi-bin". Nel nostro caso, dobbiamo eliminare l'intera directory cgi, e quindi dovremo utilizzare l'opzione -X (eXclude) con il pattern, "*cgi*" per eliminarne qualsiasi traccia:
wget -Sr -l 1 -R "*cgi*" www.funnystuff.com
Consideriamo ora il caso in cui siano presenti collegamenti a file su altri server che non volete siano seguiti (ad esempio, "doc10.html" potrebbe puntare ad articoli di approfondimento che magari volete visitare in un secondo tempo). In questo caso, ci conviene fornire una lista di domini sui quali è consentito prelevare file. Introduciamo quindi l'opzione -D che indica il "domain acceptance", ovvero i domini dai quali è accettato il download, limitando il dowload dei file collegati al nostro documento, ai soli domini funnystuff.com e happystuff.com
wget -Sr -l 1 -D funnystuff.com,happystuff.+
com www.funnystuff.com
Ovviamente, più generico è il dominio, più host sono interessati: se, ad esempio, avessi specificato solamente il dominio .it, la ricerca sarebbe rimasta entro i confini dei server italiani, un campo di ricerca comunque vasto.
Oltre che per livelli e per domini, c'è un terzo limite da considerare, che consente di specificare un quota, ovvero una dimensione massima oltre il quale non verrà scaricato più nulla. Occorre fare attenzione però al fatto che tale limite non viene applicato ai singoli file: quindi, se durante il download di un file questo viene superato, wget cesserà di funzionare solo dopo aver portato a termine l'ultima operazione e non prima. Ricordando che il limite può essere espresso in byte (default), in kilobyte (k) o in megabyte (m), se volessimo scaricare solo 10 Mb di file dovremmo scrivere la seguente linea di comando:
wget -Sr -l 1 -Q10m -D funnystuff.com,happystuff.+
com www.funnystuff.com
I mirror
Oltre che per scaricare singoli file, wget può essere utilizzato per creare vere e proprie copie aggiornate di interi siti web o ftp, grazie alle opzioni di timestamping che consentono di scaricare da un sito solo quei file che risultano cambiati dall'ultimo download (-N). Non solo, è anche possibile fare in modo che questa operazione non influisca negativamente sulle prestazioni del collegamento ad internet, grazie alla possibilità di diluire nel tempo il download. Possiamo, volendo, preparare un file di testo o html, contenente tutte le url da scaricare, passandolo poi al programma grazie allo switch -i, oppure evitare che l'hostname venga utilizzato per creare la directory che conterrà il sito, o ancora, possiamo tagliare dall'albero che ricreeremo un certo numero di direcotry (--cut-dirs)
Ad esempio, il comando:
wget -r -l 1 -A gif,jpg www.funnystuff.com
creerà nella directory corrente il file doc10.html nella sottodirectory "www.funnystuff.com", mentre il comando :
wget -r -l 1 -A gif,jpg -nH --cut-dirs=2 www.funnystuff.com
lo crea nella directory "dir3/doc10.html".
Infine, cosa fare se un donwload si interrompe per qualsiasi ragione? Senza bisogno di usare getright, provate l'opzione -c e riprenderete li dove vi eravate fermati senza perdere tempo a prelevare di nuovo tutto. Ultimo problema che vogliamo affrontare: diciamo che vogliamo scaricare un sito molto grosso, e che le operazioni dureranno almeno un giorno. Come fare per non tenere occupata una shell per 24 ore? Anche qui le cose non sono troppo difficili; basta usare aprire la stringa di comando con nohup e chiudere la serie delle opzioni con un -b (background) e vi ritroverete anche con un file di log. Facciamo un esempio: voglio scaricare tutto il sito di www.funnystuff.com. In questo caso, per essere sicuro, introduciamo anche l'opzione -m (mirror) che consentirà di creare una copia fedele del sito e l'opzione -t (tentativi) seguita da 0, per consentire al programma di tentare un numero infinito di volte l'operazione di mirroring, nel caso questa dovesse interrompersi per qualche ragione:
nohup wget -m -t0 -b www.funnystuff.com
Scaricare in ftp
Finora abbiamo visto wget come strumento per il web ma questo è decisamente limitativo: specificando nell'url il protocollo ftp potremo tranquillamente "mirrorare", interi depositi ftp con tutte le opzioni che abbiamo già visto per il web
Facciamo subito una precisazione, però: se le risorse su web sono generalmente accessibili senza dovere identificarsi con login e password, con l'ftp il discorso cambia. Per i siti anonimi non c'è problema: wget tenterà di default di collegarvisi passando dei dati di login anonimi standard. Per le aree protette da login e password particolari vi è il problema di passare sulla linea di comando i dati relativi all'account che si vuole utilizzare per accedere al sito. In questo caso, ipotizzando di volere accedere al server ftp ftp.funnystuff.com come utente pippo, con password pluto, e di copiare il contenuto della directory paperoga, la precedente linea di comando diventerà:
nohup wget -r -l0 -t0 -retr-symlinks -b pippo:pluto@:ftp.www.+
funnystuff.com/paperoga
il che ci assicura che verranno seguiti anche i link simbolici.
Quelle che noi abbiamo visto sono solo alcune delle decine e decine di opzioni che fanno di wget uno dei programmi più versatili per internet. Ovviamente, non basterebbero molte pagine per analizzare nel dettaglio ogni minimo aspetto del programma, coperto comunque in maniera soddisfacente dalla documentazione che troverete nell'archivio nel quale viene distribuito wget. Ciò che più conta, ora, è familiarizzare con questo strumento per poi essere liberi di sperimentare a proprio piacimento le decine di varianti che possiamo introdurre nel suo comportamento di base. Ricordate, però, che per operazioni frequenti e ripetitive, una volta che avete trovato la riga di comando che più vi soddisfa, vi conviene scrivere un file .wgetrc (che potrete mettere nella vostra home o in /usr/local/etc/wgetrc per definire delle opzioni per tutti gli utenti), dove potrete riportare per esteso tutte le informazioni che vorrete passare al programma. La sintassi di questo file è davvero semplice e, una volta compreso il funzionamento di wget da linea di comando vi sarà molto facile scriverne uno.