Récupération automatique des images de Bing
Le but de cet article est de développer un petit script en Perl permettant de récupérer automatiquement les images de la page d'accueil du moteur de recherche Bing.
Une fois le script développé, on planifiera son exécution afin de récupérer les images chaque jour automatiquement (sous XP, Vista et Linux).
Principe
Le principe est assez simple :
- se connecter sur www.bing.com
- parcourir le code source pour trouver l'URL de l'image du jour
- télécharger l'image
Le langage Perl
Pour réaliser ces opérations, nous voulons privilégier un langage de programmation :
- proposant des méthodes simples d'accès au web. Si on peut éviter d'implémenter le protocole HTTP et de manipuler des sockets, c'est mieux !
- permettant la manipulation de chaînes de caractères afin de parcourir le code source simplement et d'en retirer les informations nécessaires.
Le langage Perl satisfait ces deux points :
- la librairie libwww-perl permet de manipuler simplement des objets réseaux sans avoir à ouvrir soi même les connexions
- les expressions régulières font partie intégrante du langage et restent le meilleur moyen de manipuler des chaînes de caractères actuellement
Je ne vais pas détailler ici l'installation de Perl (sous Windows, allez voir du côté d'ActivePerl).
L'exécution d'un script perl se fait par la commande suivante (en admettant que le dossier bin de Perl soit dans votre Path) : perl <nom_du_script>.pl
Réalisation du script
Structure de la page d'accueil de Bing
Si on analyse la structure de la page d'accueil de Bing avec un outil comme Dragonfly ou Firebug, on se rend compte que l'image se situe dans une balise div dont l'id est bgDiv. On se rend compte également, en affichant la source de la page, que cette balise existe effectivement, mais qu'elle est vide. En réalité, l'image est affichée dans la div (avec un joli effet de Fade In) grâce à Javascript.
C'est embêtant car notre script pourra récupérer le code source de la page, mais en aucun cas interpréter le code Javascript et mettre à jour la structure de la page. Le but, c'est pas de faire un navigateur web hein...
Heureusement, en fouillant un peu plus le code source, on s'aperçoit que l'URL de l'image est présente dans le code javascript. Pour la page d'aujourd'hui, on a le code suivant :
g_img={url:'\/fd\/hpk2\/SpiceMarket_FR-FR2573271226.jpg',id:'bgDiv',d:200,cN:'_SS',crN:'bIm',hash:'122'};
Script Perl
On va donc pouvoir se connecter à la page d'accueil de Bing pour en récupérer sa source, et ensuite, à l'aide d'une expression régulière, récupérer l'adresse de l'image :
use LWP::Simple;
# URL vers bing
my $bing_url = 'http://www.bing.com';
# Récupération du code source
my $bing_source = get($bing_url);
# Récupération de l'URI de l'image
if ($bing_source =~ /g_img={url:'([^']+)/)
{
my $img_uri = $1;
}
# L'image n'a pas été trouvée
else
{
die 'Image introuvable...';
}
Voilà à quoi ressemble notre code pour le moment.
L'instruction use LWP::Simple permet d'inclure le module Simple de la librarie LWP (libwww-perl). Ce module est très simple et très limité puisqu'il permet juste de récupérer le code source d'une page. Ca tombe bien, c'est ce que nous voulons faire. Afin de récupérer le code source, on utilise la fonction get en lui passant en paramètre l'URL de la page.
L'expression régulière est assez simple, on repère le bloc de texte débutant par g_img={url:' et on capture (grâce aux parenthèses) le texte entre apostrophes. On récupère ce que l'on a capturé avec $1 (ici, ce motif n'est présent qu'une seule fois dans la page).
A ce stade, si on affiche le contenu de la variable $img_uri on se rend compte que les caractères / sont échappés à l'aide du caractère . On va donc nettoyer l'URI de l'image en supprimant les .
Ensuite, on va extraire de l'URI le nom du fichier image. De cette façon on enregistrera l'image sur le disque dur avec ce nom. Ca nous donne :
# Récupération de l'URI de l'image
if ($bing_source =~ /g_img={url:'([^']+)/)
{
my $img_uri = $1;
$img_uri =~ s/\\//g; # Suppression des caractères d'échappement
# Nom de l'image
my $img_name = $img_uri;
$img_name =~ /\/([^\/]+)$/;
$img_name = $1;
}
Afin de récupérer le nom de l'image, il nous suffit de prendre l'URI de l'image, depuis le dernier caractère / exclus jusqu'à la fin de la chaîne.
Nous avons donc l'URL complète vers l'image. On peut maintenant s'y connecter, de la même façon que pour la connexion à la page d'accueil, et l'enregistrer dans un fichier.
Le script complet :
use LWP::Simple;
# URL vers bing
my $bing_url = 'http://www.bing.com';
# Récupération du code source
my $bing_source = get($bing_url);
# Récupération de l'URI de l'image
if ($bing_source =~ /g_img={url:'([^']+)/)
{
my $img_uri = $1;
$img_uri =~ s/\\//g; # Suppression des caractères d'échappement
# Nom de l'image
my $img_name = $img_uri;
$img_name =~ /\/([^\/]+)$/;
$img_name = $1;
# Récupération de l'image
my $img = get($bing_url . $img_uri);
open(SORTIE, ">$img_name");
binmode(SORTIE); # Les images sont des fichiers binaires
print SORTIE $img;
close(SORTIE);
}
# L'image n'a pas été trouvée
else
{
die 'Image introuvable...';
}
On commence par se connecter à l'URL de l'image. On ouvre un fichier en écriture dont le nom est le nom de l'image. On spécifie que le fichier est binaire et on écrit le contenu de l'image à l'intérieur du fichier. Enfin, on ferme le fichier.
Planification
Sous Windows (XP et Vista)
Sous Windows, nous allons utiliser le Planificateur de tâches.
Sous XP :
- se rendre dans le Panneau de configuration / Tâches planifiées.
- faire un clic droit puis sélectionner Nouveau / Tâche planifiée
- faire un clic droit sur le nouvelle tâche planifiée puis Propriétés
- dans l'onglet Tâche, dans le champ Exécuter, taper : perl "<chemin_vers_script><nom_script>.pl"
- dans l'onglet Planification, choisissez l'heure à laquelle vous voulez que le téléchargement ait lieu, ainsi que la fréquence
Sous Vista :
- se rendre dans le Panneau de configuration / Système et maintenance / Tâches planifiées
- cliquer sur Créer une tâche dans le menu Actions à droite
- donner un nom à la tâche, puis dans l'onglet Déclencheurs, spécifier quand la tâche doit démarrer
- dans l'onglet Action, cliquer sur le bouton Nouveau
- Action : Démarrer un programme
- Programme/script : perl
- Ajouter des arguments (facultatif) : <chemin_vers_script><nom_script>.pl
Pour fonctionner, le dossier contenant l'exécutable de Perl (perl.exe) doit se trouver dans le PATH de Windows. Afin d'ajouter le dossier dans le PATH :
Windows XP :
- Touche Windows + Pause puis onglet Avancé
- Bouton Variables d'environnement
- Dans la liste Variables système, cliquer sur Path puis sur le bouton Modifier
- Ajouter à la liste : <dossier_perl>bin
Windows Vista :
- Touche Windows + Pause puis Paramètres système avancés
- Bouton Variables d'environnement
- Dans la liste Variables système, cliquer sur Path puis sur le bouton Modifier
- Ajouter à la liste : <dossier_perl>bin
Systèmes de type Unix
Les systèmes de type Unix permettent de planifier des tâches grâce à l'outil Crontab. Pour éditer la crontab, il faut taper la commande crontab -e.
Pour exécuter la tâche tous les jours à 11h par exemple, il faudra rajouter la ligne :
00 11 * * * perl <chemin_vers_script>/<nom_script>.pl
Pour plus d'information pour planifier vos tâches, vous pouvez regarder sur Wikipedia Crontab.
Bilan
Voilà comment créer, de manière assez simple, une tâche automatisée qui va chercher une image sur un site Internet. On pourrait très simplement modifier ce script pour qu'il aille chercher des informations (météo, news, ...) de manière automatique.
Il faudrait également modifier le script pour prendre en paramètre un dossier de sortie, où les images seront stockées. En effet, en ligne de commandes, l'image est enregistrée à l'endroit où on a exécuté la commande. En revanche avec les tâches planifiées, il est plus difficile de trouver où a été téléchargée l'image.
Commentaires
Pierre
- 18/02/2010 à 18:13:26 - # 1À ce propos, tu connais WWW:Mechanize ? Un outil absolutissimement puissant pour manipuler des pages web et simuler un humain !
Daniel
- 30/04/2010 à 14:55:55 - # 2Ah oui je viens de regarder, ça a l'air pas mal effectivement.
En plus avec mon anti-spam de merde, y a moyen que je me fasse bien spammer lol.
CodeKiller
- 23/08/2010 à 12:43:07 - # 3Bonjour,
J'obtiens un "Image introuvable... at XXX\Récup Image.pl line 32."
J'ai testé avec Google (en mettant en dur l'URI du logo de Google) et ça fait la même chose...
J'ai l'impression qu'il n'arrive pas à récupérer le code source de la page car quand je fais :
my $bing_source = get($bing_url);
die $bing_source;
J'obtiens :
IO::Socket::INET: Timeout ...propagated at "numéro de ligne de l'instruction die"
Je suppose donc que l'instruction "get" ne fonctionne pas...
Bien à vous.
Daniel
- 23/08/2010 à 17:36:07 - # 4C'est bizarre... t'as bien mis le "use LWP::Simple;" avant d'appeler la fonction get ?
Le code que tu as écrit va systématiquement faire un "die". Il faudrait que tu testes quelque chose comme ça :
my $bing_source = get($bing_url);
print $bing_source;
A ce moment là ça devrait t'afficher le code source de la page de Bing. Est-ce bien le cas ?
Nouveau commentaire