web-dev-qa-db-fra.com

Le tableau HTML ne s'affiche pas dans le fichier source

J'essaie d'extraire les données d'une table sur une page Web à l'aide de R (package rvest). Pour ce faire, les données doivent être dans le fichier source HTML (c'est là que rvest les recherche apparemment), mais dans ce cas ce n'est pas le cas. 

Toutefois, les éléments de données sont affichés dans la vue Éléments du panneau Inspecter:

 The table's elements are shown in the Elements view of the Inspect panel

Le fichier source montre une table vide:

 view-source file shows an empty table

Pourquoi les données sont-elles affichées sur l'élément inspect mais pas sur le fichier source? Comment puis-je accéder aux données de la table au format html? Si je ne peux pas accéder via html, comment puis-je modifier ma stratégie de nettoyage Web?

* La page Web est https://si3.bcentral.cl/siete/secure/cuadros/cuadro_dinamico.aspx?idMenu=IPC_VAR_MEN1_HIST&codCuadro=IPC_VAR_MEN1_HIST

Fichier source: view-source: https: //si3.bcentral.cl/siete/secure/cuadros/cuadro_dinamico.aspx? IdMenu = IPC_VAR_MEN1_HIST & codCuadro = IPC_VAR_MEN1_HIST


EDIT: une solution utilisant R est appréciée

7
David Jorquera

Les données sont plus que probablement chargées dynamiquement à partir d'une source de données ou d'une API. Vous pouvez gratter la table remplie en envoyant une demande GET à la page Web et en grattant la page après le chargement des données!

4
Brady Ward

Votre cible est un site Web complexe et dynamique, raison pour laquelle vous ne pouvez pas le supprimer facilement. Pour accéder à la page sur laquelle je pense que vous vous posez la question, je dois d’abord aller à la page d’accueil , puis cliquer sur "Cuentas Nacionales" dans le menu de gauche. Ce clic provoque une demande POST qui envoie des données de formulaire indiquant apparemment la vue suivante à présenter, qui est apparemment stockée côté serveur dans une session. C'est pourquoi vous ne pouvez pas accéder directement à l'URL cible. c'est la même URL pour plusieurs affichages différents. 

Afin de gratter la page, vous allez avoir besoin de script d'un navigateur pour suivre les étapes pour accéder à la page, puis enregistrez la page rendue dans un fichier HTML. Vous devriez alors pouvoir utiliser rvest pour extraire le fichier. données du fichier. (@hrbrmstr souligne que vous n'avez absolument pas besoin de scripter un navigateur pour obtenir les données, car vous n'avez pas besoin d'obtenir les données en grattant une page rendue. Plus d'informations à ce sujet plus tard.)

À ce stade (décembre 2018), PhantomJS est obsolète et la meilleure recommandation consiste à utiliser du chrome sans tête. Pour créer suffisamment de script pour naviguer dans un site de plusieurs pages, vous utilisez Selenium WebDriver avec ChromeDriver pour contrôler sans tête, chrome . Voir cette réponse _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Pour que cette méthode fonctionne avec un script Python. La documentation de Selenium contient des informations sur l'utilisation d'autres langages de programmation, notamment Java, C #, Ruby, Perl, PHP et JavaScript. Utilisez le langage que vous préférez. 

Le plan général du script (avec des extraits Python) serait:

  • Démarrer Chrome en mode sans tête
  • Aller chercher la page d'accueil
  • Attendez que la page soit complètement chargée. Je ne suis pas sûr de la meilleure façon de procéder dans ce cas, mais vous pouvez probablement interroger la page pour rechercher les données de la table à remplir et attendre de les trouver. Voir Attentes de sélénium explicites et implicites .
  • Trouvez le lien par le texte du lien link = driver.find_element_by_link_text("Cuentas Nacionales")
  • Cliquez sur le lien link.click()
  • Encore une fois, attendez que la page se charge
  • Obtenez le code HTML en utilisant driver.getPageSource() et enregistrez-le dans un fichier.
  • Chargez ce fichier dans rvest

Il semble qu'il soit possible de faire tout cela depuis R en utilisant seleniumPipes . Consultez sa documentation pour savoir comment effectuer les étapes ci-dessus. Utilisez findElement("link text", "Cuentas Nacionales") %>% elementClick pour rechercher et cliquer sur le lien. Utilisez ensuite getPageSource() pour obtenir le source de la page et le transférer dans rvest ou XML ou quelque chose pour rechercher et analyser la table. 

Remarque latérale: @hrbrmstr fait remarquer qu'au lieu de créer un script pour un navigateur afin de parcourir la page, vous pouvez suivre manuellement toutes les étapes du navigateur, extraire les demandes et les données de réponse appropriées à l'aide des outils de développement du navigateur. vous pouvez éventuellement créer un script pour un ensemble de requêtes HTTPS et d’analyseurs de réponses qui généreront une requête qui renverra les données souhaitées. Puisque hrbrmstr l’a déjà fait pour vous, il vous sera plus facile, dans ce cas précis, de couper et coller leurs réponses, mais en général, je ne recommande pas cette approche car elle est difficile à mettre en place et risque fort de se rompre à l'avenir , et difficile à réparer quand ça casse. Et pour les personnes qui ne se soucient pas de la maintenabilité à long terme, puisque ce tableau ne change que tous les mois, vous pouvez encore plus facilement naviguer manuellement vers la page et utiliser le navigateur pour l’enregistrer dans un fichier HTML et le charger dans le fichier. Script R.

2
Old Pro

Ceci est possible avec rvest car l'iframe final utilise un formulaire standard. Pour utiliser simplement rvest, vous devez exploiter une session, une chaîne d'agent utilisateur et les informations que vous avez déjà collectées concernant les liens directs vers l'iframe. 

library(rvest)
library(httr)

# Change the User Agent string to tell the website into believing this is a legitimate browser
uastring <- "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"

# Load the initial session so you don't get a timeout error
session <- html_session("https://si3.bcentral.cl/siete/secure/cuadros/home.aspx", user_agent(uastring))

session$url

# Go to the page that has the information we want
session <- session %>%
  jump_to("https://si3.bcentral.cl/Siete/secure/cuadros/arboles.aspx")

session$url

# Load only the iframe with the information we want
session <- session %>%
  jump_to("https://si3.bcentral.cl/siete/secure/cuadros/cuadro_dinamico.aspx?idMenu=IPC_VAR_MEN1_HIST&codCuadro=IPC_VAR_MEN1_HIST")

session$url
page_html <- read_html(session)

# Next step would be to change the form using html_form(), set_values(), and submit_form() if needed.
# Then the table is available and ready to scrape.
settings_form <- session %>% 
  html_form() %>%
  .[[1]] 

# Form on home page has no submit button,
# so inject a fake submit button or else rvest cannot submit it.
# When I do this, rvest gives a warning "Submitting with '___'", where "___" is
# often an irrelevant field item.
# This warning might be an rvest (version 0.3.2) bug, but the code works.
fake_submit_button <- list(name = NULL,
                           type = "submit",
                           value = NULL,
                           checked = NULL,
                           disabled = NULL,
                           readonly = NULL,
                           required = FALSE)
attr(fake_submit_button, "class") <- "input"
settings_form[["fields"]][["submit"]] <- fake_submit_button

settings_form <- settings_form %>%
  set_values(DrDwnAnioDesde = "2017",
             DrDwnAnioDiario = "2017")

session2 <- session %>%
  submit_form(settings_form)
1
Adam Sampson

Les données sont très probablement chargées via un framework JavaScript. La source d'origine est donc modifiée par JavaScript. 

Vous auriez besoin d'un outil capable d'exécuter le JavaScript, puis de supprimer le résultat pour les données. Vous pouvez également appeler directement l'API de données et obtenir les résultats au format JSON. 

EDIT: J'ai eu quelques succès avec Microsoft PowerBI pour gratter les tables Web, voici un lien vers un exemple si cela fonctionne pour vous. https://www.poweredsolutions.co/2018/05/14/new-web-scraping-experience-in-power-bi-power-query-using-css-selectors/

1
Richard Hubley