Download batch multipli con Linux



Vi è mai capitato di dover effettuare dei download multipli in maniera automatizzata? Supponiamo per esempio di trovarci sul web e vedere un’immagine che ci piace, ad esempio questa:

http://www.galleriasanlorenzo.com/atout/portfolio/photos/20_608.jpg

dopo aver notato che ci piace abbastanza, notiamo anche un’altra cosa: sullo stesso sito sono presenti altre immagini simili, tutte con lo stesso pattern, ossia:

http://www.galleriasanlorenzo.com/atout/portfolio/photos/20_xxx.jpg

dove “xxx” è un numero sempre diverso.

In questo tutorial vedremo come con Linux sia possibile effettuare facilmente il download batch di queste immagni. Ma non ci accontentiamo: vogliamo avviare più download in parallelo, così da ottimizzare la banda. Vediamo come fare ciò utilizzando la comodissima bash.

1 – Ciclare su tutte le immagini

Dato che non sappiamo quante immagini ci saranno a priori, è bene provarle tutte, alla peggio otterremo un bell’errore 404 su quelle che non esistono (la cosa non ci da fastidio). Per il ciclo useremo il for, con una variabile che possiamo chiamare NUM.

for ((NUM=0; NUM<=999; NUM++)); do
...
done

In questo caso abbiamo ciclato su 999 immagini, ma la scelta è arbitraria. Le immagini saranno così referenziate:

http://www.galleriasanlorenzo.com/atout/portfolio/photos/20_${NUM}.jpg

2 – Download

Per scaricare le immagini possiamo usare il sempre utile comando wget:

wget http://www.galleriasanlorenzo.com/atout/portfolio/photos/20_${NUM}.jpg

Così facendo, però, prima dell’inizio del download successivo bisogna aspettare il completamento di quello corrente, che non è quello che vogliamo. Una soluzione potrebbe essere questa:

wget http://www.galleriasanlorenzo.com/atout/portfolio/photos/20_${NUM}.jpg >/dev/null 2>&1 &

3 – Download multipli

Così facendo, i download partiranno tutti insieme (o quasi) e ciò potrebbe essere un problema specie se ci sono troppi file. Bisogna limitare il numero di download, come fare? Possiamo, prima di iniziare un download, controllare quantio processi ci sono già in coda e attendere finché la coda non si liberi. Il comando è questo:

NUMDL=`jobs | grep -c wget`
while [ $NUMDL -ge 10 ]
do
sleep 1
NUMDL=`jobs | grep -c wget`
done

In questo modo, se la coda è piena (supponiamo in questo caso di volere 10 download in parallelo) attendiamo un secondo e ricontrolliamo, così finché non sia maggiormante vuota.

4 – Tutto insieme

Siamo pronti per mettere tutto insieme, lo script è questo:

#!/bin/bash
for ((NUM=0; NUM<=999; NUM++)); do
NUMDL=`jobs | grep -c wget`
while [ $NUMDL -ge 10 ]
do
sleep 1
NUMDL=`jobs | grep -c wget`
done
wget http://www.galleriasanlorenzo.com/atout/portfolio/photos/20_${NUM}.jpg >/dev/null 2>&1 &§
done

Ovviamente possiamo migliorarlo per renderlo universale, in modo da poter scaricare una qualsiasi sequenza di immagini, oltre che parametrico nel download multiplo, i limiti sono dati solo dalla fantasia. Lo script che uso io è questo:

#!/bin/bash
ARG=4
if [ $# -ne "$ARG" ]
then
echo "Usage: `basename $0` <basename (use "#" for number)> <start> <end> <number of dls>"
exit $E_ERR_ARG
fi

BASE=$1
START=$2
END=$3
MAXDL=$4

NUMDIGITS=`echo -n $BASE | grep -o "#" | wc -l`
LEFT=`echo -n $BASE | grep -o "^[^#]*"`
RIGHT=`echo -n $BASE | grep -o "#[^#]*$" | grep -o "[^#]*$"`

for ((NUM=$START; NUM <= $END; NUM++))
do
NUMDL=`jobs | grep -c wget`
while [ $NUMDL -ge $MAXDL ]
do
sleep 1
NUMDL=`jobs | grep -c wget`
done
FILETODL=`printf "$LEFT%0${NUMDIGITS}d$RIGHT" $NUM`
#echo "Wgetting $FILETODL..."
wget "$FILETODL" >/dev/null 2>&1 &
done

Annunci sponsorizzati:
Condividi su Facebook Condividi su Twitter!
Pinterest