Aspirer les photos du site Google Picasa depuis Linux
Un petit exercice de script Shell ludique et utile pour aspirer toutes les photos d'une gallerie de Google Picasa (les grand format, pas les petites vignettes en aperçu hein).
\r\nNote : Pour passer les explications vous pouvez allez directement en bas de page pour voir le script final.
Sur Google Picasa il est possible de rechercher des photos, par exemple sur le moteur de recherche si je tape "eau verte" voici le résultat :
http://picasaweb.google.com/lh/view?q=eau+verte&psc=G&filter=1Si on clique sur une des photos on tombe sur une page de présentation détaillée, et ensuite si on clique sur la petite loupe en haut à droite on a accès à la photo en gros (pas la photo d'origine en haute définition mais en qualité correcte pour du web quand même).
Le but de cet exercice est d'aspirer toutes ces photos grand format depuis un bon vieux shell sous Linux (ouvrez un xterm ou tout autre interprêteur de commandes).
Pour ce faire nous allons utiliser le fil RSS qui se trouve en bas de la page de résultat. Revenez sur la page de résultat :
http://picasaweb.google.com/lh/view?q=eau+verte&psc=G&filter=1Repérez le fil RSS en bas à droite (lien discret en bleu clair intitulé RSS), qui nous emmène à cette adresse :
http://picasaweb.google.com/data/feed/base/all?alt=rss&kind=photo&access=public&filter=1&q=eau+verte&hl=frSi votre navigateur sait afficher des fils RSS en format xml vous devriez voir la liste de
toutes les photos sur une seule page avec un aperçu et sous chaque aperçu, dans une zone grissée (sous Firefox c'est présenté comme ça),
un lien direct vers l'image en grand format ! Repéser au passer l'adresse URL de l'image grand format (ci-dessus en gras, le domaine du serveur, et le nom du fichier image) :
http://lh3.ggpht.com/_4RD1_O-HPlk/SH4-F2-xpzI/AAAAAAAAAtg/WvTX-70jZrc/IMG_3222.JPGBien nous allons aspirer cette page xml comme base de travail, en utilisant bien suuur l'incontournable
wget (copier/coller l'adresse URL du fil RSS pour obtenir celle ligne de commande, l'option -O permet de préciser dans quel fichier vous voulez sauvegarder la page) :
# wget "http://picasaweb.google.com/data/feed/base/all?alt=rss&kind=photo&access=public&filter=1&q=eau+verte&hl=fr" -O eau-vert.xml
--15:17:52-- http://picasaweb.google.com/data/feed/base/all?alt=rss&kind=photo&access=public&filter=1&q=eau+verte&hl=fr
Résolution de picasaweb.google.com... 74.125.47.91, 74.125.47.93, 74.125.47.136, ...
Connexion vers picasaweb.google.com|74.125.47.91|:80...connecté.
requête HTTP transmise, en attente de la réponse...200 OK
Longueur: non spécifié [application/rss+xml]
Saving to: `eau-vert.xml'
15:17:54 (354 KB/s) - « eau-vert.xml » sauvegardé [436443]
Si on inspecte maintenant ce fichier :
# cat eau-vert.xml
<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:e<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:exif='http://schemas.google.com/photos/exif/2007' xmlns:geo='http://www.w3.org/2003/01/geo/wgs84_pos#' xmlns:gml='http://www.opengis.net/gml' xmlns:georss=...
Tout est sur une signe ligne, c'est illisible. On va ajouter un saut de ligne (n) après chaque fin de balise (>) pour rendre ça plus lisible en utilisant la commande de manipulation/substitution de chaine incontournable ...
sed , bien suuur (Michel si tu nous lit ....) , et on redirige le flux de résultat dans un 2nd fichier appelé par exemple eau-vert2.xml :
# sed "s/>/>n/g" eau-vert.xml > eau-vert2.xml
Note : Explication de l'expression de substitution
s/>/>n/g que l'on passe en argument à sed (faites
man sed pour en savoir plus) :
les '/' sont des séparateurs (on peut utiliser ce qu'on veut) et la syntaxe est grossièrement :
(mode)(séparateur)(expression régulière de ce qu'il faut remplacer)(séparateur)(expression de remplacement)(separateur)(option)
s = mode substitution
/ = séparateur
g = option globale : répéter la substitution autant de fois que possible sur la ligne
donc "s/>/>n/g" signie remplace stp les '>' par '> retour à la ligne' autant de fois que possible sur la ligne ... facile non ?
Bien vous pouvez ouvrir le fichier résultat avec un éditeur texte pour voir ce que ça donne (c'est du bête XML), ou bien plus brute (j'aime) on va rechercher les lignes qui peuvent nous intéresser dans ce fichier, avec
grep bien suuur qui permet de faire des recherches par exepression régulière sur des fichiers.
Que cherche-t-on ? les adresses URL des grandes photos ! on a repéré précédemment l'adresse URL d'une image grand format :
http://lh3.ggpht.com/_4RD1_O-HPlk/SH4-F2-xpzI/AAAAAAAAAtg/WvTX-70jZrc/IMG_3222.JPGOn va donc rechercher cette adresse dans notre fichier pour voir comme elle se présente :
# grep "lh3.ggpht.com/_4RD1_O-HPlk/SH4-F2-xpzI/AAAAAAAAAtg/WvTX-70jZrc/IMG_3222.JPG" eau-vert2.xml
<enclosure type='image/jpeg' url='http://lh3.ggpht.com/_4RD1_O-HPlk/SH4-F2-xpzI/AAAAAAAAAtg/WvTX-70jZrc/IMG_3222.JPG' length='0'/>
<media:content url='http://lh3.ggpht.com/_4RD1_O-HPlk/SH4-F2-xpzI/AAAAAAAAAtg/WvTX-70jZrc/IMG_3222.JPG' height='1200' width='1600' type='image/jpeg' medium='image'/>
2 lignes contiennent notre expression de recherche dans ce fichier. On va se baser sur la 1ere (peu importe) :
<enclosure type='image/jpeg' url='http://lh3.ggpht.com/_4RD1_O-HPlk/SH4-F2-xpzI/AAAAAAAAAtg/WvTX-70jZrc/IMG_3222.JPG' length='0'/>
et partir du principe que le fichier contient sans doute pour chaque photo que l'on chercher une ligne du type :
<enclosure type='image/jpeg' url='L'adresse URL de la photo grand format' length='0'/>
donc on va faire une seconde recherche pour sortir du fichier toutes les lignes commençant par "<enclosure" (le chapeau '^' en début d'expression de recherche signifie 'début de ligne') :
# grep "^<enclosure" eau-vert2.xml
<enclosure type='image/jpeg' url='http://lh6.ggpht.com/_QazqhSxzAHo/SEg2ZgfXceI/AAAAAAAAAE8/S3EmJuC9pQc/IMG_3320.JPG' length='0'/>
<enclosure type='image/jpeg' url='http://lh3.ggpht.com/_tmk41YElywg/SQYbLrBiVWI/AAAAAAAADzw/mLf1Y8D0Zqc/P1100614.JPG' length='0'/>
<enclosure type='image/jpeg' url='http://lh5.ggpht.com/_Ybu1KqzNSk4/RpnDmaIWJCI/AAAAAAAAAH0/QAG-dyWIiCM/DSC00713.JPG' length='0'/>
...
et voici toutes les belles adresses directes vers nos grandes photos !
on va maintenant épurer la sortie pour ne garder que les URL (avec
sed pour la manipulation/substitution de chaine).
on pourrait comme précédemment rediriger le flux du résultat ci-dessus dans un 3eme fichier puis travailler avec sed sur ce fichier,
mais on peut aussi directement rediriger le flux de résultat sur la commande sed, comme sur la plupart des commandes systèmes, en utilisant le tube
| :
# grep "^<enclosure" eau-vert2.xml | sed "s/.*url='//"
http://lh6.ggpht.com/_QazqhSxzAHo/SEg2ZgfXceI/AAAAAAAAAE8/S3EmJuC9pQc/IMG_3320.JPG' length='0'/>
http://lh3.ggpht.com/_tmk41YElywg/SQYbLrBiVWI/AAAAAAAADzw/mLf1Y8D0Zqc/P1100614.JPG' length='0'/>
http://lh5.ggpht.com/_Ybu1KqzNSk4/RpnDmaIWJCI/AAAAAAAAAH0/QAG-dyWIiCM/DSC00713.JPG' length='0'/>
...
explication rapide de l'expression de substitution
s/.*url='// : remplace n'importe quel caractère (.) et autant qu'y en a (*) suivis des caractères url= et d'une apostrophe (') par rien.
on va aussi nettoyer à droite et oter les "' length..." , en utilisant l'expression s/' length.*// :
# grep "^<enclosure" eau-vert2.xml | sed "s/.*url='//" | sed "s/' length.*//"
http://lh6.ggpht.com/_QazqhSxzAHo/SEg2ZgfXceI/AAAAAAAAAE8/S3EmJuC9pQc/IMG_3320.JPG
http://lh3.ggpht.com/_tmk41YElywg/SQYbLrBiVWI/AAAAAAAADzw/mLf1Y8D0Zqc/P1100614.JPG
http://lh5.ggpht.com/_Ybu1KqzNSk4/RpnDmaIWJCI/AAAAAAAAAH0/QAG-dyWIiCM/DSC00713.JPG
...
Note : sed peut accepter directement plusieurs expression en utilisant l'option -e , la ligne de commande peut donc aussi s'écrire avantageseument comme ça :
# grep "^<enclosure" eau-vert2.xml | sed -e "s/.*url='//" -e "s/' length.*//"
http://lh6.ggpht.com/_QazqhSxzAHo/SEg2ZgfXceI/AAAAAAAAAE8/S3EmJuC9pQc/IMG_3320.JPG
http://lh3.ggpht.com/_tmk41YElywg/SQYbLrBiVWI/AAAAAAAADzw/mLf1Y8D0Zqc/P1100614.JPG
http://lh5.ggpht.com/_Ybu1KqzNSk4/RpnDmaIWJCI/AAAAAAAAAH0/QAG-dyWIiCM/DSC00713.JPG
...
Bon maintenant il suffit de passer chaque ligne en argument à la commande wget pour qu'il aspire la photo et qu'il l'enregistre sur votre disque dur.
Pour ça on va faire une boucle (while ...do; done) qui pour chaque ligne d'adresse va lancer un wget url :
# grep "^<enclosure" eau-vert2.xml | sed -e "s/.*url='//" -e "s/' length.*//" | while read url; do wget $url; done
...
Connexion vers lh4.ggpht.com|209.85.129.190|:80...connecté.
requête HTTP transmise, en attente de la réponse...200 OK
Longueur: 261698 (256K) [image/jpeg]
Saving to: `IMGP0544.JPG'
16:37:49 (599 KB/s) - « IMGP0544.JPG » sauvegardé [261698/261698]
...
Connexion vers lh3.ggpht.com|209.85.129.136|:80...connecté.
requête HTTP transmise, en attente de la réponse...200 OK
Longueur: 312405 (305K) [image/jpeg]
Saving to: `IMG_3222.JPG'
16:37:50 (612 KB/s) - « IMG_3222.JPG » sauvegardé [312405/312405]
...
Voilà, cette ligne de commande va télécharger toutes les photos dans le dossier de travail où vous vous trouvez.
Explication : la liste d'adresses URL est redirigée via un tube (|) vers while read url; do qui signifie tant que (while) je peux lire (read) des lignes et les placer dans une variable 'url' ,
faire (do) , aspirer cette adresse (wget $url) . fin de boucle tant que (done).
les ';' servent à séparer les instructions pour tout écrire sur une seule ligne, mais on pourrait l'écrire aussi de façon équivalente sur plusieurs lignes en faisant un retour chariot en lieu et place de chaque ';' .
Amélioration : on peut écrire la totalité de notre script en 1 ligne (bon allez, 2 pour que ce soit plus lisible) sans passer par les fichiers eau-verte.xml et eau-verte2.xml mais en utilisant des tubes à la place pour rediriger le flux de résultat de chaque commande vers la suivante.
# picasa="http://picasaweb.google.com/data/feed/base/all?alt=rss&kind=photo&access=public&filter=1&q=eau+verte&hl=fr"
# wget -q "$picasa" -O - | sed "s/>/>n/g" | grep "^<enclosure" | sed -e "s/.*url='//" -e "s/' length.*//" | while read url; do wget $url; done
Note : l'option "-q" de wget signifie quiet (n'affiche pas les infos et traces habituelles) et l'option "-O -" (au lieu de "-O fichier") signifie : écrit ce que tu télécharges sur la sortie standard au lieu d'un fichier. Et comme ensuite on utilise un tube (|) on redirige ce flux vers la commande suivante : sed. etc...
Conclusion :
pour aspirer des photos de neige bleue, remplacer simplement "eau+verte" par "neige+bleue" :
# picasa="http://picasaweb.google.com/data/feed/base/all?alt=rss&kind=photo&access=public&filter=1&q=neige+bleue&hl=fr"
# wget -q "$picasa" -O - | sed "s/>/>n/g" | grep "^<enclosure" | sed -e "s/.*url='//" -e "s/' length.*//" | while read url; do wget $url; done
Bien sur vous vous assurerez des droits de ces photos avant toute utilisation. Même si on voit "access=public" dans l'URL de recherche Picasa, ça ne signifie pas que ces photos sont libres de droits. Surtout pour un usage commercial !
7 620 clics - Créé le 26/11/2008 par Tito - Modifié le 19/12/2008