Problemi con i link
E' chiaro che potete sperimentale l'uso di wget anche senza essere
collegati ad internet. Basta infatti installare un server web (consigliati
Xitami [www.xitami.com] oppure Apache [www.apache.org]), creare o copiare
un sito nella document root e quindi puntare wget sul localhost.
Ad es. a scopo di prova sul mio localhost ho messo questi file:
file /home/httpd/html/prova_wget/index.htm
<HTML>
<HEAD>
<TITLE>indice in /prova_wget</TITLE>
</HEAD>
<BODY>
<H1>indice in /prova_wget</H2>
<A HREF="dir/index.htm">indice in /prova_wget/dir</A>
</BODY>
</HTML>
file /home/httpd/html/prova_wget/dir/index.htm
<HTML>
<HEAD>
<TITLE>indice in /prova_wget/dir</TITLE>
</HEAD>
<BODY>
<H1>indice in /prova_wget/dir</H2>
<A HREF="../index.htm">indice in /prova_wget</A>
</BODY>
</HTML>
file /home/httpd/html/prova_wget/dummy.htm
<html>
<head><title>dummy</title></head>
<body><h1>dummy</h1></body></html>
Avviato manualmente il server apache col comando:
# apachectl start
oppure xitami con
# cd /home
# xitami -s
Ho aperto il browser netscape per controllare che il piccolo sito di prova
funzioni. Basta scrivere
localhost/prova_wget
in Location
(cioè nella casella di testo sono si immette l'URL da seguire).
Quindi fare qualche prova di passaggio da un file all'altro seguendo i
link.
Adesso date il comando:
$ wget -nd -r localhost/prova_wget
Ecco il log che vedo sulla mia macchina (sulla vostra sarà simile):
--11:21:38-- http://localhost:80/prova_wget
=> `prova_wget'
Connecting to localhost:80... connected!
HTTP request sent, awaiting response... 301 Moved Permanently
Location: http://martiny.rett.polimi.it/prova_wget/ [following]
--11:21:38-- http://martiny.rett.polimi.it:80/prova_wget/
=> `index.html'
Connecting to martiny.rett.polimi.it:80... connected!
HTTP request sent, awaiting response... 200 OK
Length: 158 [text/html]
0K -> [100%]
11:21:38 (154.30 KB/s) - `index.html' saved [158/158]
Loading robots.txt; please ignore errors.
--11:21:38-- http://martiny.rett.polimi.it:80/robots.txt
=> `robots.txt'
Connecting to martiny.rett.polimi.it:80... connected!
HTTP request sent, awaiting response... 404 Not Found
11:21:38 ERROR 404: Not Found.
--11:21:38-- http://martiny.rett.polimi.it:80/prova_wget/dir/
=> `index.html.1'
Connecting to martiny.rett.polimi.it:80... connected!
HTTP request sent, awaiting response... 200 OK
Length: 161 [text/html]
0K -> [100%]
11:21:38 (157.23 KB/s) - `index.html.1' saved [161/161]
FINISHED --11:21:38--
Downloaded: 319 bytes in 2 files
Vi troverete nella directory corrente due file html:
$ ls index.html*
index.html index.html.1
Notate che i file htm sono stati rinominati come .html (lo ha fatto il
server Apache) e che il file dummy.htm non linkato non è stato scaricato.
Adesso col browser andate a navigare la copia che vi siete scaricati.
Potete usare netscape o altro browser. Io userò un browser in modo testo
(Lynx), perchè non serve un cannone per sparare ad una mosca:
$ lynx index.html
Notate che il link all'altra pagina (che è stata salvata col nome
index.html.1) non funziona più. Questo perchè di default wget non cambia i
link nei file html: li scarica così come sono sul server. Se non avreste
usato l'opzione -nd, facendo:
$ wget -r localhost/prova_wget
vi sareste trovati con una directory col nome della vostra macchina (nel
mio caso attualmente martiny.rett.polimi.it), con questi file:
martiny.rett.polimi.it/prova_wget/index.html
martiny.rett.polimi.it/prova_wget/dir/index.html
Ora il link nel primo index.html non funziona. Wget non è in grado di
aggiustare i link quando usate l'opzione -nd in questi casi, quindi
conviene non usarla. Supponendo che volete evitare la creazione della
directory chiamata "martiny.rett.polimi.it" occorre usare invece l'opzione
-nH (oppure --no-host-directories):
$ wget -rnH localhost/prova_wget
Avrete quindi scaricato a partire dalla directory corrente i seguenti
file:
prova_wget/index.html
prova_wget/dir/index.html
Se poi volete evitare anche la creazione di un certo numero di directory
usate l'opzione --cut-dirs=NUMBER (che non ha un nome più breve).
Ad es. nel nostro caso se scrivo:
$ wget -r --cut-dirs=1 localhost/prova_wget
scarico nella directory corrente questi file:
martiny.rett.polimi.it/index.html
martiny.rett.polimi.it/dir/index.html
Mentre se combino le due cose:
$ wget -r -nH --cut-dirs=1 localhost/prova_wget
scarico nella directory corrente:
index.html
dir/index.html
Se poi ancora voglio mettere nella directory mia_dir
quei due file di prima scrivo:
$ wget -r -nH --cut-dirs=1 -P mia_dir localhost/prova_wget
Un'invasione di ragni sul web
Finora ho mostrato semplici esempi d'uso di wget, senza preoccuparmi di un
fatto: fin dove arriva a scaricare wget?
Occorre precisare questo fatto. Con l'opzione -r, di default wget non
segue i link ad altri server presenti in una pagina (ad es. se in una
pagina che state scaricando da un server che non è quello di Snoopy :) c'è
un link a http://www.peanuts.com, wget non lo segue): per fargli seguire
anche i link a siti esterni, occorre l'opzione -H alias --span-hosts, che
comunque sarà di rara utilità.
Con la sola -r quindi wget spazzola i siti specificati fermandosi comunque
a 5 livelli di profondità di ricorsione rispetto all'URL iniziale. Di
default quindi il ragnetto wget va in qualunque directory dell'host, e non
segue più i link solo se questi sono al sesto livello di profondità
rispetto all'url iniziale. Per spiegare meglio supponete di avere un file
0.htm che linki un file 1.htm che a sua volta linki 2.htm, ecc... Un
comando del tipo wget -r host.domain/1.htm si ferma allo scaricamento di
5.htm (compreso).
Per sperimentare predisponete questi file in localhost/level/
0.htm: <a href="1.htm">1.htm</a>
1.htm: <a href="2.htm">2.htm</a>
2.htm: <a href="3.htm">3.htm</a>
3.htm: <a href="4.htm">4.htm</a>
4.htm: <a href="5.htm">5.htm</a>
5.htm: <a href="6.htm">6.htm</a>
6.htm: <a href="7.htm">7.htm</a>
7.htm: 7.htm
Date poi il comando:
$ wget -nH -r localhost/level/0.htm
Scaricherete così i seguenti file:
level/0.htm
level/1.htm
level/2.htm
level/3.htm
level/4.htm
level/5.htm
Il problema è che cinque livelli di profondità potrebbero essere in alcuni
casi troppo (nel senso che scaricate molta fuffa che non interessa e
riempie inutilmente l'hard disk e sovraccarica inutilmente la rete) e in
altri troppo pochi (nel senso che non riuscite a scaricare le pagine a
livello più profondo di un sito che vi interessa avere tutto).
L'opzione -l DEPTH (alias --level=DEPTH) permette di settare a piacimento
la profondità massima di recupero: il default è -l 5. -l inf specifica una
profondità infinita, e a meno che non volete riempirvi l'hard disk (e
probabilmente far bloccare il sistema) con un gran pezzo del web, conviene
usarla solo in combinazione con altre opzioni limitative, come -np (alias
--no-parent). Quest'ultima vi assicura che quando usate l'opzione -r solo
i file all'interno dell'ultima directory specificata nell'URL saranno
recuperati, in pratica il ragnetto wget non uscirà mai da quella
directory. Spesso vi interessa scaricare tutta la gerarchia di file che si
diparte da una certa directory di un host: in tal caso, le opzioni -l inf
e -np insieme (oltre ovviamente alla -r) fanno al caso vostro. Tenete
conto che se nell'URL non indicate un file particolare, e se nella
directory non è presente un file indice (index.htm, index.html sono di
solito i nomi standard per il file iniziale di un sito o di una sua parte,
ma questo dipende dalla configurazione del server remoto), il server web
solitamente (a meno che non sia configurato diversamente) vi restituisce
un file .html con l'elenco della directory che può essere seguito quindi
da wget come un qualsiasi altro file .html
Es.
$ wget -nH -r -l1 localhost/level/0.htm
scaricherà solo i file:
level/0.htm
level/1.htm
$ wget -nH -r -l2 localhost/level/0.htm
scaricherà solo i file:
level/0.htm
level/1.htm
level/2.htm
mentre
$ wget -nH -r -l0 localhost/level/0.htm
scaricherà tutto, essendo -l 0 equivalente a -l inf:
level/0.htm
level/1.htm
level/2.htm
level/3.htm
level/4.htm
level/5.htm
level/6.htm
level/7.htm
Supponete ora di modificare il file 1.htm aggiungendo un link
diretto al file 5.htm, in modo che risulti questo:
1.htm: <a href="2.htm">2.htm</a><p><a href="5.htm">5.htm</a>
Se date poi il comando:
$ wget -nH -r localhost/level/0.htm
scaricherete i seguenti file:
level/0.htm
level/1.htm
level/2.htm
level/3.htm
level/4.htm
level/5.htm
Come vedete non cambia nulla. Se invece 1.htm è questo:
1.htm: <a href="2.htm">2.htm</a><p><a href="6.htm">6.htm</a>
lo stesso comando wget di prima provoca ora lo scaricamento di tutto (da
0.htm fino a 7.htm)
Questi esempi dovrebbero chiarire il funzionamento di -r: nel primo caso
wget scarica nell'ordine 0.htm, 1.htm, 2.htm, 3.htm, 4.htm, 5.htm
fermandosi qui poichè ha raggiunto profondità di ricorsione 5. Poi inizia
la catena dei ritorni e si ritorna ad analizzare il prossimo link
contenuto in 1.htm, che punta a 5.htm. Ma poichè questo è stato già
scaricato, esso non viene analizzato di nuovo, perciò il file 6.htm, pur
essendo linkato nel file 5.htm non viene scaricato.
Nel secondo caso, invece si scarica da 0.htm a 5.htm, poi si ritorna ad
analizzare 1.htm, ritornando ad una profondità di ricorsione 1 e poichè
1<5, si segue il link a 6.htm presente in 5.htm. Questo porta ad una
profondità di ricorsione 2, che è ancora < 5, quindi si segue il link a
7.htm presente in 6.htm. Siamo arrivati a profondità di ricorsione 3,
ancora minore di 5, ma 7.htm non presenta alcun link, quindi si ritorna ad
analizzare 0.htm, che però non presenta alcun link. A questo punto
l'algoritmo ricorsivo di wget termina. Ai programmatori il termine
profondità di ricorsione e il concetto di elaborazione ricorsiva saranno
familiari, ma spero che anche i non addetti ai lavori abbiano capito.
Come si fa per scaricare una sola pagina html con tutte le immagini
collegate (ma non gli altri documenti eventualmente collegati), salvandola
in una certa directory? Non occorre aspettare che la Micro$oft faccia
uscire la prossima versione del suo browser, per fortuna.
$ wget -P page_dir -nH --cut-dirs=n -rl1 -np -A gif,jpg http://www.host.domain/path/page.html
Niente di difficile ragazzi: stiamo dicendo a wget di salvare tutto in
page_dir (-P page_dir), di non creare una directory col nome dell'host
(-nH), di non creare un albero di directory per riprodurre il path
(--cut-dirs=n; sostituire ad n il numero di directory di path), di partire
scaricando il file http://www.host.domain/path/page.html e seguire
ricorsivamente tutti i link in esso contenuti e nient'altro (-rl1) e di
accettare solo file il cui nome termina con gif o jpg (-A gif,jpg), oltre
al file html specificato. Notate che se i file di immagine si trovano in
una ulteriore sottodirectory a partire da path, questa viene ricreata, in
modo che i link in page.html alle immagini funzionino. L'opzione -np serve
per evitare di uscire dal path. Questo metodo tuttavia non funziona quando
le immagini di page.html sono salvate in qualche directory non contenuta
sotto path. In tal caso usate il comando (ancora più semplice):
$ wget -r -l1 -k -A gif,jpg http://www.host.domain/path/page.html
Notare l'opzione -k che converte eventuali link non relativi (tipo
/img/image.gif) in link relativi (tipo ../img/image.gif)