Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème de parsing-scraping avec R

    10 février 2024 à 14:29:21

    Bonjour,

    J'ai des problèmes avec le code ci-dessous. La fonction test est utilisée pour obtenir des données d'un site web et fonctionne assez bien pour toutes les valeurs de i entre 2 et 33000 (peu importe). Mais lorsqu'il s'agit de récupérer toutes les pages avec ma boucle for, j'obtiens des erreurs de parsing et plusieurs lignes identiques dans mon dataframe. J'ai essayé d'ignorer les lignes problématiques avec tryCatch mais cela ne résout pas le problème des lignes multiples (et saute beaucoup de données). Pouvez-vous m'aider ? Je vous remercie.

    library(rvest)
    library(chromote)
    library(jsonlite)
    library(dplyr)
    
    
    test=function(i){
      b$ChromoteSession$new()
      p=b$Page$loadEventFired(wait_ = FALSE)
      b$Page$navigate(paste("https://www.ecologie.gouv.fr/sru_api/api/towns/",i,sep=""),wait_ = FALSE)
      b$wait_for(p)
     b$Runtime$evaluate('document.documentElement.outerHTML')
      content=read_html(html$result$value)
      data_json=html_text(content)
      df=fromJSON(data_json)
      return(df)}
    
    
    
    ma_liste= list()
    n=100
    for (i in 2:n){
      tryCatch({
        ma_liste= c(ma_liste, list(test(i)))
      })
    }
    
    ma_liste
    dataframe = do.call(rbind, ma_liste)
    dataframe =as.data.frame(dataframe)
    

    -
    Edité par Alexique0 10 février 2024 à 14:36:05

    • Partager sur Facebook
    • Partager sur Twitter
      12 février 2024 à 16:04:30

      identifier les numéros qui posent soucis et vérifier ce que donne la page en question dans le navigateur.
      ensuite pourquoi passer par du parsing, et pas par une requête GET


      Après, il y a un jeu de données disponible en licence ouverte sur https://www.data.gouv.fr/fr/datasets/communes-et-inventaire-sru/#/information si les données conviennent.
      • Partager sur Facebook
      • Partager sur Twitter
        12 février 2024 à 16:48:59

        Les pages problématiques sont bien disponibles en ligne sans soucis. Une requête GET fournit l'erreur suivante :

        Erreur lors de la requête HTTP :Failure when receiving data from the peer. 
        

        Peut-être un problème de pare-feu ? Les jeux de données que vous mentionnez recensent 2000 communes seulement et non les 34000 totales qui m'intéressent.

        -
        Edité par Alexique0 12 février 2024 à 16:58:21

        • Partager sur Facebook
        • Partager sur Twitter
          12 février 2024 à 17:10:55

          pages disponibles ne veut pas dire que les pages renvoient les données que tu attends, c'est à dire un json (ici ça semble être le cas, puisque le GET renvoie une erreur et non pas un résultat json). Il se peut que les données pour cette valeur ne soient pas accessibles, d'où cette erreur.

          Avec ton code, tu obtiens combien de résultat au final ? (je pense que ce nombre se rapproche du nombre de communes du jeu de données)
          • Partager sur Facebook
          • Partager sur Twitter
            12 février 2024 à 17:30:59

            Par exemple, pour les 100 premiers ID, j'obtiens seulement 86 lignes dans mon dataframe. J'arrive à obtenir les id manquant individuellement. Je ne vois donc pas d'où vient le problème. J'aimerais pouvoir upload des captures d'écran mais je ne sais pas comment faire.

            • Partager sur Facebook
            • Partager sur Twitter
              12 février 2024 à 19:52:37

              tu enregistres tes captures écran en fichier image et tu les  joins  via la boite de dialogue qui apparait en cliquant sur l'icone image (tu peux redimensionner la boite de dialogue qui apparait si elle est trop grande)
              • Partager sur Facebook
              • Partager sur Twitter
                13 février 2024 à 18:06:12

                Bon, en fait, je me suis aperçu que j'avais des problèmes de proxy/pare-feu qui sur certaines itérations de ma boucle, posait des problèmes. Donc j'ai corrigé cela en demandant à la boucle de relancer les itérations erronées. Ca donne le code ci-dessous et ça marche très bien chez moi.

                library(rvest)
                library(chromote)
                library(jsonlite)
                library(dplyr)
                library(progress)
                
                test = function(i) {
                  b = ChromoteSession$new()
                  p =b$Page$loadEventFired(wait_ = FALSE)
                  b$Page$navigate(paste("https://www.ecologie.gouv.fr/sru_api/api/towns/", i, sep = ""), wait_ = FALSE)
                  b$wait_for(p)
                  html = b$Runtime$evaluate('document.documentElement.outerHTML')
                  content=read_html(html$result$value)
                  data_json = html_text(content)
                  df = fromJSON(data_json)
                b$close()
                  return(df)
                }
                
                start.time = Sys.time()
                ma_liste = list()
                n =100
                pb = progress_bar$new(total = n)
                for (i in 2:n) {
                  pb$tick()
                  retry = TRUE
                  while (retry) {
                    tryCatch({
                      ma_liste = c(ma_liste, list(test(i)))
                      retry = FALSE  # Pas d'erreur, donc pas besoin de réessayer
                    }, error = function(e) {
                      message("", i, ": ", conditionMessage(e))
                      Sys.sleep(0.001)  # Attendre un certain temps avant de réessayer
                    })
                  }
                }
                
                dataframe =do.call(rbind, ma_liste)
                dataframe = as.data.frame(dataframe)
                end.time = Sys.time()
                time.taken = round(end.time - start.time,2)
                time.taken
                

                -
                Edité par Alexique0 13 février 2024 à 20:03:40

                • Partager sur Facebook
                • Partager sur Twitter
                  13 février 2024 à 18:50:21

                  Si tu rajoutes ta temporisation (Sys.sleep(0.001)) dans ta boucle principale, ça ne réduirait pas le nombre d'erreurs?
                  • Partager sur Facebook
                  • Partager sur Twitter
                    13 février 2024 à 20:24:59

                    Non, pas vraiment. Par contre, R ouvre une page chrome par itération donc ma mémoire a évidemment explosé. J'ai donc rajouté la ligne b$close() pour fermer chaque page après extraction des données. C'est mieux ^^ et là, ça prend environ 1 seconde pour 4 itérations donc ça va le faire. Je réessaierai demain avec une requête GET plutôt...

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Problème de parsing-scraping avec R

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    • Editeur
                    • Markdown