Ya en artículos anteriores hemos aprendido como interactuar con una página web (Enlace) y también a como extraer datos de tablas ubicadas en webs (Enlace). En el último caso lo hicimos con tablas cuyos datos eran estáticos, es decir, no cambiaban. Lo que haremos ahora es extraer datos de tablas cuyos datos pueden cambiar.
Para el ejercicio vamos a usar esta web como ejemplo: Enlace. Como vemos, hay una tabla, llamémosla, principal, cuyos datos dependen de una lista desplegable con tres opciones y un control de fechas (“picker”). Si bien hay un botón “Descargar datos”, en esta ocasión lo que nos interesa es extraer los datos directamente desde la web.
Lo primero es obtener el nombre, id o clase de los objetos que queremos usar así que usaremos la herramienta “Inspeccionar” de Chrome.
Entonces, el id del combobox es “data_interval” y el del picker es, justamente, “picker”. Unos detalles importantes a tomar en cuenta son qué; en el combobox hay tres opciones por ende, y viendo el orden, usaremos la propiedad “SelectedIndex” para elegir lo que deseamos (no olvidar que los índices comienzan en 0) y lo otro es que, veremos la forma en que en el picker están ingresados los valores de fechas predeterminadas, lo que nos da luces de como ingresarlos nosotros. Otro detalle es que cuando se elige una opción en el combobox o en el picker, los datos se actualizan de manera automática. Esto último es algo a lo que debemos tomar mucha atención pues, como verán, si la web no detecta estás acciones, no actualizará los datos de la tabla.
Entonces, si queremos elegir “Mensual” y fechas entre 01/01/2017 y el 01/03/2019, nuestro código quedaría así (no olvidar activar las referencias a “Microsoft HTML Object Library”):
Dim IE As Object
Dim doc As HTMLDocument
Dim htmTable As HTMLTable
Set IE = CreateObject("InternetExplorer.Application")
IE.navigate "https://es.investing.com/equities/cellnex-telecom-historical-data"
Do Until IE.ReadyState = 4
DoEvents
Loop
With IE
.document.getElementById("data_interval").selectedIndex = 2
.document.getElementById("picker").Value = "01/01/2017 - 01/03/2019"
.Visible = True
End With
Set IE = Nothing
La web cargada se verá así:
Como ven el combobox nos muestra “Mensual” pero ¡el picker no cambió las fechas! ¿Qué pasó? Si le damos un simple click al botón del picker que despliega los calendarios, veremos esto:
¡Aparecen las fechas enviadas con VBA! Es decir, sí fueron ingresadas pero no mostradas. Ah, otro dilema es que ¡la tabla no actualizó los datos! Pero si presionamos el botón “Aceptar” que aparece en la imagen anterior lograremos actualizar los datos. Entonces, usando el “Inspeccionar” de Chrome veremos que el id del botón para desplegar el picker es “widget” y el del botón “Aceptar” es “applyBtn” y para que las fechas se vean tal cual las mandamos y se actualice la tabla lo que haremos ahora es desplegar los calendarios del picker, enviarle un click al botón “Aceptar” y replegar el picker. Entonces, en nuestro código la parte del “With” debería quedar así:
With IE
.document.getElementById("data_interval").selectedIndex = 2
.document.getElementById("picker").Value = "01/01/2017 - 01/03/2019"
.document.getElementById("widget").Click
.document.getElementById("applyBtn").Click
.document.getElementById("widget").Click
.Visible = True
End With
Corremos la macro y ahora sí tenemos la tabla actualizada:
Ahora sí, solo nos falta extraer los datos de la tabla. Como ya hemos visto cómo hacerlo en un artículo anterior, básicamente usaremos los mismos códigos para lograrlo, pero en esta ocasión en lugar de usar el objeto “Tag” y el índice de la tabla (aunque también podríamos usarlo) lo haremos a través de su id que ya vimos es “curr_table”. Como no en realidad no es de nuestro interés ver la web, nos bastará trabajar en ella sin mostrarla e incluso cerraremos el Internet Explore usando “Quit”. Ah, por cierto, agregaremos un “Application.Wait” para dar un segundo para asegurar de que los datos de la tabla tengan tiempo de cargar. Nuestra macro quedará así:
Sub ExtraerDatos()
Dim IE As Object
Dim doc As HTMLDocument
Dim htmTable As HTMLTable
Dim nFilas As Integer, nColumnas As Integer, x As Integer, y As Integer
Set IE = CreateObject("InternetExplorer.Application")
IE.navigate "https://es.investing.com/equities/cellnex-telecom-historical-data"
Do Until IE.ReadyState = 4
DoEvents
Loop
With IE
.document.getElementById("data_interval").selectedIndex = 2
.document.getElementById("picker").Value = "01/01/2017 - 01/03/2019"
.document.getElementById("widget").Click
.document.getElementById("applyBtn").Click
.document.getElementById("widget").Click
End With
Application.Wait (Now + TimeValue("00:00:01"))
Set doc = IE.document
Set htmTable = doc.getElementById("curr_table")
Let nFilas = htmTable.Rows.Length
Let nColumnas = htmTable.Rows(0).Cells.Length
For x = 1 To nFilas
For y = 1 To nColumnas
Cells(x, y).Value = htmTable.Rows(x - 1).Cells(y - 1).innerText
Next y
Next x
IE.Quit
Set IE = Nothing: Set doc = Nothing: Set htmTable = Nothing
End Sub
Como verán, en nuestra hoja activa hallaremos todos los datos que hemos elegido y ni siquiera fue necesario que se vea el Internet Explorer. Espero se haya entendido. Hasta la próxima.
Abraham Valencia