Recuperer le Xpath du site "info climat"

Bonjour,
Malgré la lecture du post https://community.jeedom.com/t/extraire-valeur-vent-rafale-infoclimat/107495, je n’arrive pas a recuperer le xpath pour les valeurs

Voici les copies image:

Je clique de droit sur la rafale actuel (48.3), je clique sur « inspecter » et voici ce que j’obtiens:
xpath

Si je copie le xpath, et que je le mets dans mon bloc code suivant, ca marche pas:

// On récupère les tags du scénario
$tags = $scenario->getTags();
// On extrait l'éventuel tag maj
$maj = $tags['#maj#'];

// Lapte-verne 

$url = "https://www.infoclimat.fr/observations-meteo/temps-reel/lapte-verne/000CY.html";
$data = file_get_contents($url);
@$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($data);
libxml_use_internal_errors(false);

$xpath = new DomXPath($dom);

//Rafales
$node = $xpath->query("/html/body/div[8]/div[4]/div/div[4]/table/tbody/tr[12]/td[4]/span[5]"); 
if ($node->length > 0) {
    $valeur = $node[0]->nodeValue;
    $resultat = cmd::byString("#[Maison][Lapte-verne][Rafales]#")->event($valeur);
    $scenario->setLog("Résultat de la commande Rafales : " . $resultat);
} else {
    $scenario->setLog("XPath incorrect : Aucun élément trouvé.");
}

Voici le log:

[2024-02-22 15:37:57][SCENARIO] -- Start : Scenario lance manuellement.
[2024-02-22 15:37:57][SCENARIO] - Exécution du sous-élément de type [action] : code
[2024-02-22 15:37:57][SCENARIO] Exécution d'un bloc code
[2024-02-22 15:37:57][SCENARIO] XPath incorrect : Aucun élément trouvé.
[2024-02-22 15:37:57][SCENARIO] Fin correcte du scénario

Pouvez vous me venir en aide svp ?

Merci

Bonjour,
Ça ne fonctionne pas avec le « xpath complet ». Il suffit d’une pub en plus ou en moins, une refonte du site et tout est décalé.
Avec ce xpath copié depuis Google Chrome, ça fonctionne actuellement:

$node = $xpath->query('//*[@id="resptable-releves"]/tbody/tr[1]/td[4]/span[5]'); 

[2024-02-22 16:21:11][SCENARIO] Résultat de la commande Rafales : 51.5
Au lieu de prendre tout le document avec les pubs, seule cette partie est utilisée:
image

PS: Dans le post que vous citez au début, pour la même demande (vitesse des rafales), la solution était différente:

$node = $xpath->query("//*[@id=\"resptable-releves\"]/tbody/tr[1]/td[".$i."]/span[4]/span[2]");

Preuve que la méthode fonctionne, mais peut varier dans le temps.

Oui, les colonnes changent dans le temps, voire parfois en dynamique.

Comme j’en avais marre de bidouiller les numéros de colonne, j’ai changé le code pour rechercher les intitulés qui sont plus constants. Voici ce que ça donne :

// On récupère les tags du scénario
$tags = $scenario->getTags();
// On extrait l'éventuel tag maj
$maj = $tags['#maj#'];

// Pluie annuelle

  $url = "https://www.infoclimat.fr/climatologie/annee/".date("Y")."/xxx.html";
  $data = file_get_contents($url);
  @$dom = new DOMDocument();
  libxml_use_internal_errors(true);
  $dom->loadHTML($data);
  libxml_use_internal_errors(false);
  $xpath = new DomXPath($dom);

  for ($k = 12; $k <= 16; $k++) {
    $node = $xpath->query("//*[@id=\"tableau-releves\"]/tr[".$k."]/td[1]/b");
    $texte = $node[0]->nodeValue;
    //$scenario->setLog("Libellé :  $texte");
    if (stripos($texte, 'Cumul') !== FALSE) {
     $scenario->setLog("Match trouvé pour \"Cumul`\"");
     $node = $xpath->query("//*[@id=\"tableau-releves\"]/tr[".$k."]/td[14]/span");
     $precipitations = $node[0]->nodeValue;
     $scenario->setLog("Précipitations annuelles :  $precipitations");
     if ($precipitations != "") {
       cmd::byString("#[Météo][Infoclimat][Pluie année]#")->event($precipitations);
     }
    }
  }


// Relevés du jour  

  $url = "https://www.infoclimat.fr/observations-meteo/temps-reel/xxx.html";
  $data = file_get_contents($url);
  @$dom = new DOMDocument();
  libxml_use_internal_errors(true);
  $dom->loadHTML($data);
  libxml_use_internal_errors(false);
  $xpath = new DomXPath($dom);


  for ($c = 2; $c <= 10; $c++) {
    $node = $xpath->query("//*[@id=\"resptable-releves\"]/thead/tr/th[".$c."]/a");
    $titre_colonne = $node[0]->nodeValue;
    //$scenario->setLog("Colonne :  $titre_colonne");
    if (stripos($titre_colonne, 'rature') !== FALSE) { $c_temperature = $c-1; } // Température
    if (stripos($titre_colonne, 'Pluie') !== FALSE) { $c_pluie = $c-1; }
    if (stripos($titre_colonne, 'Vent') !== FALSE) { $c_vent = $c-1; }
    if (stripos($titre_colonne, 'Hum') !== FALSE) { $c_humidite = $c-1; }
    if (stripos($titre_colonne, 'Pt.') !== FALSE) { $c_rosee = $c-c; }
    if (stripos($titre_colonne, 'Pression') !== FALSE) { $c_pression = $c-1; }
  }
 
  //Heure
  $node = $xpath->query("//*[@id=\"resptable-releves\"]/tbody/tr[1]/th/span");
  $nouvelle_heure = preg_replace ('#h$#','h00',$node[0]->nodeValue);
  $cmd = cmd::byString("#[Météo][Infoclimat][Heure]#");
  $ancienne_heure = $cmd->execCmd();
  $scenario->setLog("Heure ".$ancienne_heure. " vs ".$nouvelle_heure);

  //Température
  if ($c_temperature != "") {
    $scenario->setLog("Colonne température = ".$c_temperature);
    $node = $xpath->query("//*[@id=\"resptable-releves\"]/tbody/tr[1]/td[".$c_temperature."]/span[1]");
    $nouvelle_temp = $node[0]->nodeValue;
    $scenario->setLog("Température ".$nouvelle_temp);
  }

  if ( ($nouvelle_heure != $ancienne_heure || $maj) && ($nouvelle_heure != "") && ($nouvelle_temp != "") )  {

    //Mise à jour heure et température
    $scenario->setLog("=> Mise à jour");
    $cmd->event($nouvelle_heure);
    cmd::byString("#[Météo][Infoclimat][Température]#")->event($nouvelle_temp);

    //Pluie
    if ($c_pluie != "") {
      $scenario->setLog("Colonne pluie = ".$c_pluie);
      $node = $xpath->query("//*[@id=\"resptable-releves\"]/tbody/tr[1]/td[".$c_pluie."]");   
      cmd::byString("#[Météo][Infoclimat][Pluie]#")->event($node[0]->nodeValue);
    }

    //Humidité
    if ($c_humidite != "") {
      $scenario->setLog("Colonne humidité = ".$c_humidite);
      $node = $xpath->query("//*[@id=\"resptable-releves\"]/tbody/tr[1]/td[".$c_humidite."]/span[1]");
      cmd::byString("#[Météo][Infoclimat][Humidité]#")->event($node[0]->nodeValue);
    }

    //Vent
    if ($c_vent != "") {
      $scenario->setLog("Colonne vent = ".$c_vent);
      $node = $xpath->query("//*[@id=\"resptable-releves\"]/tbody/tr[1]/td[".$c_vent."]/span[2]");
      $valeur = $node[0]->nodeValue;
      if ($valeur == "km/h") {
        $node = $xpath->query("//*[@id=\"resptable-releves\"]/tbody/tr[1]/td[".$c_vent."]/span[1]"); 
        $valeur = $node[0]->nodeValue;
        cmd::byString("#[Météo][Infoclimat][Vent]#")->event($node[0]->nodeValue);
      }
    }
    
  }

Bonjour,

Il semble que lorsque je clique pour copier le Xpath, le résultat que j’obtiens est différent du vôtre. J’ai sélectionné uniquement la ligne en question et j’obtiens :

/html/body/div[8]/div[4]/div/div[4]/table/tbody/tr[1]/td[3]/span[4]

Quoi qu’il en soit, je comprends que cette méthode de récupération n’est peut-être pas fiable à long terme, car une simple mise à jour du site peut rendre le code erroné. Je vais essayer de trouver une autre solution.

@seb821, est-ce que ta solution fonctionne de manière optimale dans la durée ?

Merci pour vos contributions.

Bonjour,
Çà dépend du navigateur utilisé:

  • Avec Chrome, il y a 2 copier Xpath:

    Le Xpath est //*[@id="resptable-releves"]/tbody/tr[1]/td[3]/span[4]
    Le Xpath complet est celui que vous obtenez: /html/body/div[8]/div[4]/div/div[4]/table/tbody/tr[1]/td[3]/span[4]
  • Avec Firefox, il n’y a que le Xpath complet.

La solution de seb821 est totalement dépendante de la structure du site infoclimat et du bon vouloir de son dev.
Ça ne pourrait être fiable et durable que si infoclimat proposait une API ( qui pourrait être payante ).

Dans le plugin-meteofrance , il y a une commande qui contient la vitesse actuelle des rafales de vent:


Les vitesses des rafales des heures suivantes sont aussi accessibles.

En faite, je souhaite obtenir une information fiable d’une station proche de chez moi, et non pas des infos de météo France qui sont prise je ne sais où… Probablement a plusieurs 10ene de km, a des altitudes différentes

J’ai aussi des accès a des centrale météo Netatmo proche de chez moi, mais ça dépend de l’installation (position par rapport au maison environnante, altitude etc …)
Les vents obtenu ne correspondent pas à la réalité malheureusement…

Sinon, j’ai plus a acheter une station perso lol.
Mais ça, j’ai mois le goût (et le budget surtout :blush:)

Merci

Pour Lapte, les données sont prises par MF là:
image
Soit à 2384m du centre de Lapte fourni par l’INSEE.

C’est quasiment la même altitude qu’infoclimat:
image
C’est vous leur fournisseur de données ? :rofl:

Mais ça reste des prévisions météo.

En fait, comment obtiens-tu la fiche MF pour connaître l’endroit exact de la station météo utilisée ?
Et s’agit-il de prévisions ou de prises de mesures « in situ » ?

Merci.

C’est vous leur fournisseur de données ? :rofl:

Ca vrai que ca peut porter a confusion :sweat_smile:

La position de la station météo utilisée est fournie par MF dans les données de prévisions.
On interroge MF avec les coordonnées X.XXX et Y.YYY et MF fournit les prévisions pour la station la plus proche x.xxx et y.yyy

Ce sont des prévisions.

En fouillant un peu leur site, je viens de voir qu’ils avaient une API en XML,JSON et CSV.
C’est décrit là: API infoclimat

Pour votre localisation, Requête JSON
Le résultat est en JSON par tranche de 3 heures sur 7 jours. C’est des prévisions.

Les infos dans une tranche de 3 heures: