Télécharger des images (bash+wget)

Classé dans : Linux, Programmation | 0

Sur un de mes sites une limite d’OVH m’a posé un problème.

Lorsque l’on utilise le serveur FTP d’OVH il y a une limite sur le nombre de fichiers affichés (5000). Hors dans le cas de mon site, le dossier contient plus de 10000 images. Il est donc impossible de récupérer via FTP l’ensemble des images pour par exemple les transférer sur un autre serveur.

J’ai essayé de faire le ftp directement en ligne de commande mais la limite s’applique également.

Par contre les images sont bien la et fonctionnent car elles sont visibles sur le site dans les pages HTML.

J’ai pu confirmer cela en téléchargeant une image avec : wget URL_DE_IMAGE

La solution était donc de faire un script pour télécharger l’ensemble des images avec wget.

Les images étant numéroté (1.jpg, 1.jpg…) il suffit de faire une boucle pour incrémenter le chiffre et récupérer toutes les images.

Une des difficultés a été que par défaut si le fichier n’existe le site retourne une 404, et wget créer un fichier x.jpg, mais ce fichier contient en fait le code de la page 404.html… Ce fichier fait 401 octets il a donc fallu trouver un moyen de filtrer cela.

Voici le code commenté du script que j’ai utilisé

#!/bin/bash

# 1ere image a récupérer par exemple 1 
START=$1

# dernière image par exemple 1000
END=$2 

# boucle qui traite toutes les images entre START et END 
for ((i=$START; i<=$END; i++))
do
  # URL du site avec l'image 
  URL="https://XXXX.XXXX.XX/static/images/$i.jpg"

  # check taille du fichier pour pas télécharger les 404 de 401 octets
  file_size=$(wget --spider --server-response "$URL" 2>&1 | grep "Content-Length" | awk '{print $2}')

  # affiche un message indiquant le N° du fichier en cours de traitement 
  echo "Traitement fichier $i.jpg"

  ## si taille ok le fichier est téléchargé dans le dossier courant 
  if [ $file_size -ge "402" ]; then 
    wget $URL
  fi
done

Le script s’appelle getImageOVH.sh. il faut bien lui attribuer les droits d’exécution avec : chmod +x getImageOVH.sh pour que cela fonctionne.

Le plus simple c’est de placer ce script dans un dossier du PATH, il sera ainsi accessible de n’importe ou. Par exemple dans /usr/local/bin

Utilisation du script

Se placer dans le dossier destination, (attention si un fichier local existe avec un nom identique à un fichier téléchargé il sera écrasé!). Il est possible d’ajouter un test dans le script pour éviter cela (voir ci-dessous)

Dans le dossier exécuter la commande : getImageOVH.sh 1 1000 pour récupérer les images de 1.jpg à 1000.jpg

Ne pas écraser un fichier local

Pour ne pas risquer d’écraser un fichier local il suffit d’ajouter un test pour savoir si le fichier existe déjà en local en modifiant la boucle do ..done

do
  # URL du site avec l'image 
  URL="https://XXXX.XXXX.XX/static/images/$i.jpg"

  # test si fichier existe en local 
  if [ -f $i.jpg ]; then 
     echo "$i.jpg existe, téléchargement annulé"
  else 

     # check taille du fichier pour pas télécharger les 404 qui font 401 octets
     file_size=$(wget --spider --server-response "$URL" 2>&1 | grep "Content-Length" | awk '{print $2}')

     # affiche un message indiquant le N° du fichier en cours de traitement 
     echo "Traitement fichier $i.jpg"

     ## si taille ok le fichier est téléchargé dans le dossier courant 
     if [ $file_size -ge "402" ]; then 
      wget $URL
     fi
  fi
done 

ChatGPT…

Merci à ChatGPT qui m’a aidé pour trouver comment filtrer les fichiers par rapport à leur taille et pour faire une boucle sur un INT dans un script Bash.

J’aurais pu trouver l’info en cherchant sur Google, mais la avec deux simples questions ChatGPT m’a répondu direct, en français et avec la bonne solution…