(Je n'ose pas appeler ça du data mining, même si techniquement, il s'agit bien d'aller récupérer l'information là où elle est ... :) )

Petit exercice pratique de Perl, suite à une question posée (ici) sur un forum d'alcooliques : "quels sont les domaines sur Châteauneuf du pape ayant des cuvées à forte proportion de cinsault ?" Le plus dur, c'est sans doute de trouver le "bon" site : celui-ci, tenu par un passionné danois, semble faire l'affaire. Beaucoup de domaines y sont référencés (tous ?), les noms des cuvées et les encépagements sont spécifiés (modulo les variations annuelles, mais bon ...). L'objectif est évidemment de NE PAS effectuer la recherche à la main, mais de l'automatiser, et tant qu'à faire d'y parvenir en moins de 20 lignes de code. Pour récupérer une page web, on peut utiliser le package LWP::Simple. En deux lignes :

use LWP::Simple;
my $content = get('http://www.chateauneuf.dk/en/index.htm');

Quand on regarde le code source de la page de départ, on voit ces séquences là : <a href="cdpen133.htm">Beaucastel</a> (toutes les urls sont sur le format cdpen*.htm)

On récupère donc à la fois l'url de la page et le nom du domaine avec l'expression régulière suivante (recherche "globale", en mode liste) :

my %domaine = ($content =~ m/(cdpen\d+\.htm)">(.+?)<\/a>/g);

Cela permet d'affecter un hash construit sur le modèle $domaine{url}=nom; Puis on effectue une boucle sur toutes les pages :

foreach my $page (keys %domaine) {

... dont on récupère le contenu :

	my $cdp = get('http://www.chateauneuf.dk/en/'.$page);

... que l'on parcourt :

	while ($cdp =~ /(Chateauneuf.+(\n){1}.+?(\d+)\%\s+Cinsault)/g) {

Cette regexp mérite quand même une petite explication : le détail des cuvées est écrit sur deux lignes, on ne cherche que des Châteauneuf (certaines cuvées peuvent être en Côtes du Rhône), contenant un certain pourcentage de Cinsault. Sur la page du domaine du Père Pape, on voit par exemple :

Chateauneuf du Pape Domaine du Pere Pape
2010: 65% Grenache, 20% Syrah and 15% Cinsault.

avec le code html suivant :

<b>Chateauneuf du Pape</b> <b>Domaine du Pere Pape</b><br>
      2010: 65% Grenache, 20%<span style="mso-spacerun: yes">&nbsp;S</span>yrah and 15% Cinsault.&nbsp;<br>

On cherche donc la chaîne Chateauneuf, suivie d'un certain nombre de caractères .+, d'un seul saut de ligne (\n){1}, d'un certain nombre de caractères (en mode non-greedy !) .+?, du signe % (que l'on échappe), d'un ou plusieurs espaces \s+, et enfin de la chaîne Cinsault.

On récupère les modèles qui nous intéressent :

		my $quest = $1;			
		my $percent = $3;

On vire les balises :

		$quest =~ s/<.+?>//g;

... puis la newline pour faire joli :

		$quest =~ s/\n//g;

Et on affiche enfin seulement ceux qui nous intéressent :

		if ($percent >=10) {print $domaine{$page},"\t",$quest,"\n\n";}

ET VOILA !

En résumé :

use strict;
use LWP::Simple;
my $path = 'http://www.chateauneuf.dk/en/';
my $cepage = 'Cinsault';
my $content = get('http://www.chateauneuf.dk/en/index.htm');
my %domaine = ($content =~ m/(cdpen\d+\.htm)">(.+?)<\/a>/g);

foreach my $page (keys %domaine) {
	my $cdp = get($path.$page);
	while ($cdp =~ /(Chateauneuf.+(\n){1}.+?(\d+)\%\s+$cepage)/g) {
		my $quest = $1;			
		my $percent = $3;
		$quest =~ s/<.+?>//g;		# On vire les balises
		$quest =~ s/\n//g;		# On supprime la newline
		if ($percent >=10) {print $domaine{$page},"\t",$quest,"\n\n";}
	}
}