code avant
<div class="vigilance-bulletin-status">
<strong>Aujourd’hui dimanche 17:</strong>
<br>
<strong>Encore orageux sur la Provence-Alpes-Côte d'Azur, ensoleillé ailleurs.</strong>
</div>
code après
Collons tout d'abord notre exemple : il lui a été rajouté des retour ligne, mais on va les garder pour comprendre comment ils peuvent être gérés, par contre on laisse les données encadrées par leurs balises de mise en forme ! (il n'ya jamais de retour ligne à ce niveau et s'il ya des espaces, c'est qu'ils font partie de la donnée)
Pour simuler qu'"il y ai du code avant et après... on ajoute "code avant" et "code après".
On va donc appeler un httpQuery dans notre code, par exemple (l'url ici, n'a aucune importance, mais on pourrait, puisque cet exemple provient de meteo.orange.fr, lui donner cette adresse)
$url = httpQuery ("http://meteo.orange.fr",'GET');On peut vérifier avec un echo que notre $url contient bien le texte HTML entré (puis on le supprime).
preg_match_all (Regex,texte,tableau)
En code, cela nous donnera:
preg_match_all ('##',$url,$matches);Evidemment, pour l'instant le Regex est vide, mais l'important est de savoir comment on va le construire d'une part et pour tout de suite, comment on va contrôler le résultat, cela se fera par...
print_r($matches);On va commencer par inclure dans le Regex la première ligne de code "balise" :
preg_match_all ('#<div class="vigilance-bulletin-status">#',$url,$matches);On note que cette ligne contient des guillemets, c'est pour cela que notre Regex sera identifié entre des apostrophes (on a le choix), plutôt que d'échapper les guillemets avec un antislash (on a déjà vu cela). On observe ce que cela donne (éxécution) : un indice 0 qui contient une deuxième dimension, d'indice 0 qui contient la ligne que nous avons indiqué.
#<div class="vigilance-bulletin-status">\s*<strong>#
Eh oui, ça commence à se compliquer, mais vous verrez qu'à la fin vous saurez écrire en hieroglyphes ;-).
Maintenant qu'obtenons nous ? tout à fait logiquement, la même chose, mais avec les 2 premières lignes.
#<div class="vigilance-bulletin-status">\s*<strong>(.*)</strong>#
Maintenant, on obtient un tableau avec 2 entrées principales (0 et 1) et dont la 2ème contient en indice 0 le texte mis entre parenthèses, faisons de même avec la deuxième donnée et allons jusqu'à la fin :
#<div class="vigilance-bulletin-status">\s*<strong>(.*)</strong>\s*<br>\s*<strong>(.*)\s*</strong>\s*</div>#
Houlala, hein ? :-)
On obtient donc un 3eme indice (2 puisqu'on commence à 0), dont la première entrée d'indice 0 contient notre 2eme donnée; on pourrait l'identifier par [2][0] si on voulait l'afficher, exemple, si on met un echo (qui affiche une variable simple, ici un élément du tableau) à la place de l'affichage du tableau print_r():
echo $matches[2][0];Donc voila un autre moyen, un peu plus compliqué que le précédent, mais souvent indispensable, pour obtenir notre donnée, mais la n'est pas le but, de compliquer quand on peut faire simple : le but c'est SI on avait plusieurs entrées du même type ! par exemple "météo du matin" et "prévision de l'après midi", or c'est exactement ce qu'il se passe en journée dans la page météo orange, la micro météo extraite auparavant ne prenant que la première occurence.
(tagada(tsoin(?:tsoin))turl)ututu
donnera : 1: tagadatsointurl 2: tsoin
code1 - donnée 1 - fin code 1
code2 - donnée 2a -fin code intermédiaire donnée 2a' fin code2
code2 - donnée 2b -fin code intermédiaire donnée 2b' fin code2
code2 - donnée 2c -fin code intermédiaire donnée 2c' fin code2
Dans ce cas, vous ferez un Regex pour la première donnée et mettrez un OU (barre verticale |) avec le Regex des données suivantes: Vous obtiendrez alors en index 1 la première donnée et en index 2 et 3 les groupes de sous données abc et a'b'c'
L'important à retenir c'est que la forme du code doit être constante pour un Regex donné et ce sont les répétitions de cette forme à l'intérieur du code HTML qui incrémenteront les index !
Aujourdhui
matin< --- >texte
midi< --- >texte
soir< --- >texte
Demain
matin< --- >texte
midi< --- >texte
Etant entendu que dans ce schéma, Aujourdhui et Demain sont encadrés par les même codes et de même pour les matin, midi et soir - on a volontairement omis le soir de Demain pour observer que la valeur de cet indice sera bien omise.
Si on "invente" un code les identifiant et les séparant, cela pourrait ressembler pour se calquer un peu sur notre exemple de début, à:
code avant
<div class="vigilance-bulletin-status">
<strong>Aujourdhui</strong></div>
code quelconque
<div class="vigilance-bulletin-données">
matin<strong>Orageux.</strong></div
<div class="vigilance-bulletin-données">
midi<strong>Moins orageux.</strong></div
<div class="vigilance-bulletin-données">
soir<strong>Les orages se terminent.</strong></div
code quelconque
<div class="vigilance-bulletin-status">
<strong>Demain</strong></div>
code quelconque
<div class="vigilance-bulletin-données">
matin<strong>Beau.</strong></div
<div class="vigilance-bulletin-données">
midi<strong>Grand soleil.</strong></div
code après
Je sais, cet exemple est un peu long, mais c'est un exercice d'analyse de structure, ici il n'y en a que 2 ! la première, pour Aujourdhui et Demain, la seconde pour tous les groupes "moment de la journée" - "temps"
On remarque que les groupes suivent simplement leur groupe principal Aujourdhui et Demain, pour organiser tout cela et obtenir notre tableau, nous allons donc faire :
Même si le résultat semble "compliqué", la construction sera rapide, on va le faire pas à pas pour le premier et on enchaînera pour la suite:
<div class="vigilance-bulletin-status"> // on insère ici le code espace blanc
<strong>(on remplace Aujourdhui par .* entre nos parenthèses capturantes)</strong></div>
On colle tout ceci en une seule ligne, cela donne :
<div class="vigilance-bulletin-status">\s*<strong>(.*)</strong></div>
et maintenant on enchaîne puisque vous savez faire, le Regex sera:
<div class="vigilance-bulletin-status">\s*<strong>(.*)</strong></div>
et (ou plutôt OU : |)
<div class="vigilance-bulletin-données">\s*(.*)<strong>(.*)</strong></div
cela nous donne notre Regex final:
#<div class="vigilance-bulletin-status">\s*<strong>(.*)</strong></div>|<div class="vigilance-bulletin-données">\s*(.*)<strong>(.*)</strong></div#Essayons cela immédiatement sur la base précédente (avec l'affichage du tableau):
<meteo>
<Aujourdhui>
<matin>Orageux.</matin>
<midi>Moins orageux.</midi>
<soir>Les orages se terminent.</soir>
</Aujourd'hui>
<Demain>
<matin>Beau.</matin>
<midi>Grand soleil.</midi>
</Demain>
</meteo>
Ah ! il est beau notre XML, avec ses balises principales "meteo" non ? Bon, un peu artificiel puisque la page Orange n'est pas conçue comme avec notre exemple, facilité parceque les balises sont "prédigérées" puisqu'elles réclament des ajustements (n'arrondissez pas les yeux, ce lien a été donné au début de "Mon tout premier script" !). Mais on est d'accord ? une fois que vous saurez faire ça, vous saurez extraire n'importe quoi ! c'est parti ?
C'est parti.
Dans cette démarche, on n'a pas la fermeture de la super balise, il suffit de le faire avant d'ouvrir la suivante, à condition que ce ne soit pas la première (index 0) et a la fin du foreach, on ferme la dernière super balise.
Pour se faire, on remarque que si les balises et les données peuvent être données en clair (les variables extraites par le foreach), lors de notre parcours foreach, il va falloir "stocker" notre super balise pour pouvoir l'identifier pour pouvoir la fermer ! En plus du foreach, il va donc nous falloir une variable, par exemple $sbalise et sans oublier de l'initialiser, par exemple à NULL ce qui permettra de ne la fermer que si elle contient une valeur.
Encore une petite choses et on attaque : on l'a vu dans le résultat escompté: il faut une balise globale qui encadre toutes les autres pour valider notre XML, la c'est facile, on l'écrit avant et après notre code.
foreach($matches[3] as $index => $donnée) {}On peut vérifier (entre les accolades) qu'avec un echo, on obtient bien une liste indexée des données :
echo "l'index " . $index . " pointe sur : " . $donnée . "\n";Maintenant, on va transcrire en code nos conditionnels, on fait un rappel :
$xml = "<meteo>\n"; // initialisation du xml avec la balise globaleMaintenant on peut tester avec un echo $xml; pour retrouver ce qu'on désirait (début du chapître Extraction !
$sbalise = NULL; // définit la variable, ici avec une valeur nulle
foreach($matches[3] as $index => $donnée) {
if ($matches[1][$index] != '') {
if ($sbalise != NULL) {$xml .= "</" . $sbalise . ">\n";} // fermeture super balise sauf si jamais définie
$sbalise = $matches[1][$index]; // on attribue la super balise courante
$xml .= "<" . $sbalise . ">\n"; // et on l'ouvre
}elseif ($donnée != ''){
$xml .= "<" . $matches[2][$index] . ">" . $donnée . "</" . $matches[2][$index] . ">\n"; // écriture de la donnée encadrée par sa balise
}
}
$xml .= "</" . $sbalise . ">\n"; // fermeture dernière super balise
$xml .= "</meteo>"; // fermeture balise globale
Allons sur la page : http://www.meteofrance.re/previsions-meteo-reunion/bulletin recherchez la première ligne qui sera notre "micro-bulletin" et après avoir affiché le code source, repérez la:
Et pour formellement identifier notre première phrase "micro-bulletin, nous sélectionnons :
</h1>
</div>
<div class="mod-body">
<div class="article-row">
<h2>JOURNEE DU SAMEDI 23 </h2>
<p class="p-style-2" style="clear: both;"><br/><br/>Temps plus sec avec moins de vent.<br/><br/><br/>Le réveil est lumineux .../...
Pour réaliser notre script, que nous allons tout d'abord tester, nous allons dans le bac à sable :
preg_match_all('#<div class="mod-body">\s*<div class="article-row">\s*<h2>.*</h2>\s*<p class="p-style-2" style="clear: both;"><br/><br/>(.*)<br/><br/><br/>#',$url,$matches);Vous avez remarqué que nous ne comprenons presque plus le Regex alors que nous l'avons construit en copiant/collant une partie du code source comprenant l'élément recherché encadré par du code identifiant, en entourant de parenthèse ce que nous recherchons puis en ajoutant remplaçant juste les parties retour ligne/espaces et les données variables par du code Regex! cela s'est fait presque sans efforts !
$url = strtolower($matches[1][0]);
Pour finaliser notre réussite, on ne doit prendre que le code qui se trouve sous la partie émulation, mais il faudra ne pas oublier le <?php quand vous l'enregistrerez sous un autre nom, par exemple bulletin_re.php que vous enregistrerez sur l'Eedomus dans le dossier /script puis dans notre interface Eedomus, cloner (dupliquer) notre périphérique (voir en bas de sa configuration), lui donner un autre nom, une autre icône, changer l'appel php et... c'est tout.
Cet exercice conclue donc nos didacticiels...
A VOUS