Fonction IMPORTXML sur GoogleSheet

Salut la communauté,

J’ai une petite question concernant la fonction importxml de GoogleSheet.

J’ai ajouté cette fonction sur 450 lignes, le problème est que je n’arrive pas à avoir tous les résultats au même moment : la fonction se lançant en continue, j’ai beaucoup de cellules indiquant le résultat « Loading ».

Y’a t-il un moyen de « programmer » cette fonction ? De faire en sorte qu’elle ne se lance qu’une fois / jour ?

Sans titre

Tout est là:

En français tu as : ImportXml & ImportHtml: Scraper avec Google Spreadsheet

Il faudrait mettre un delay (cc @cebri)

@ScrapingExpert la méthode a fonctionné au départ.

Mais quand je relance le script, toutes les valeurs retournées sont égales à « 0 » .

Je pense que le problème vient de la :

_« Note: In case you’re wondering why we’re adding a random number to the end of our URL, it’s because otherwise the website will be cached and the function stops importing the latest data. »

Malheureusement le problème évoqué est double:

  • Les 450 itérations s’exécutent de manière séquentielles les unes après les autres, le temps d’attente est donc très long, il faudrait être en mesure de lancer les 450 itérations en asynchrone pour qu’elles s’exécutent en //

  • D’autre part, il faut créer une fonction via un Google App Script lié directement à la Google Spreadsheet, et programmer l’exécution de cette fonction via le déclenchement d’un time-driven trigger, afin de pouvoir lancer l’extract et mise à jour des données quotidiennement.

Je reprends ce que disait Brice:

2 mécanismes entrent en jeu ici:

  1. Google met en cache les requêtes que tu executes (logique)
  2. La requete n’est executée qu’une fois, à sa création ou à l’ouverture du fichier (au bémol près mentionné en #1)

pour faire ce que tu veux, il faut donc avoir la possibilité d’excuter la requete a intervalle régulier, et non une seule fois. Importxml n’est pas fait pour ca, les google script le sont: https://www.google.com/script/start/

Je pense personnellement qu’on atteint ici très vite les limites de la fonction importxml qui n’est pas faite pour cela, d’autant plus qu’on va demander de travailler ligne par ligne… et lorsqu’on se penche sur la mécanique de fonctionnement de mise à jour des cellules dans les spreadsheet, on comprend vite qu’il faut en réalité faire un post-traitement de type: calcul de toutes les valeurs à injecter avant, puis update du contenu des cellules en une fois, via une operation de range .

En bref, pour l’avoir fait, c’est assez technique :confused:

Clairement. Autant utiliser l’addon SEO tools sur Excel qui permet la même chose sans limite et plus simplement.

Pour donner un exemple du genre de code qui peut faire fuir assez rapidement…(à noter que dans mon exemple , je voulais au contraire faire un traitement synchrone alors que la boucle forEach est de par nature asynchrone).

Ici le processus est en deux étapes: 1ère étape, on fait notre calcul interne des valeurs à injecter, hors feuille, puis 2ième étape, on met à jour directement un range de cellules avec les valeurs précédemment calculées:

  // Let's get our new data rows from some API call's JSON results
  var datarows = jsonapicall(apiurl);
  // Compte the rows headers
  var fields = Object.keys(datarows[0]);
 
  var rows = [];
        
  // Step 1 - For each JSON row retrieved, compute the spreadsheet row values to be inserted
  datarows.forEach(function(element, index){

    // Since forEach is aynchronous in JS, let's make it synchronous
    (function(elem, idx) {

      var currentpos = idx+1;
      var rowdata=[];
      
      // Foreach field of data in our JSON row, compute the associated spreadsheet current row cell value
      for(var fieldindex in fields) {
        
        var field= fields[fieldindex];
        
        if(elem.hasOwnProperty(field))
          rowdata.push(elem[field]);  //Logger.log("Treating field '"+field+"', which value is='"+element[field]+"'");
        else
          rowdata.push("");  //Logger.log("Treating empty field '"+field+"'");
      }
           
      rows.push(rowdata);
      
    })(element, index);
    
  });
  
  var sheet = SpreadsheetApp.getActiveSheet();

  // Step 2 -  Update the Spreadsheet cells values with previously computed data rows
  var range = sheet.getRange(sheet.getLastRow() + 1, 1, rows.length, rows[0].length);
  range.setValues(rows);
1 « J'aime »

@Camille En effet, ça fonctionne pour dépanner !

Merci pour vos réponses, au top comme d’habitude :wink:

J’ai trouvé cet article, je ne sais pas si ça peut aider …

Merci pour l’article Mik, ça rejoint un peu le code que j’ai partagé récemment, et qui pointe du doigt les problèmes d’update de cells en bulk/micro.