Eliminación de datos del sitio web usando vba
Estoy intentando extraer datos del sitio web: http://uk.investing.com/rates-bonds/financial-futures a través de vba, como el precio en tiempo real, es decir, el Bobl alemán a 5 años, el T-Bond estadounidense a 30 años, he probado Excel. consulta web pero solo elimina todo el sitio web, pero me gustaría eliminar solo la tarifa, ¿hay alguna forma de hacerlo?
Hay varias maneras de hacer esto. Esta es una respuesta que escribo con la esperanza de que se encuentren todos los conceptos básicos de la automatización de Internet Explorer al buscar las palabras clave "extrayendo datos del sitio web", pero recuerde que nada vale más que su propia investigación (si no quiere ceñirse a códigos preescritos que no puedes personalizar).
Tenga en cuenta que esta es una forma que no prefiero en términos de rendimiento (ya que depende de la velocidad del navegador), pero que es buena para comprender la razón detrás de la automatización de Internet.
1) Si necesito navegar por la web, ¡necesito un navegador! Entonces creo un navegador Internet Explorer:
Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")
2) Le pido al navegador que navegue por la página web de destino. Mediante el uso de la propiedad ".Visible", decido si quiero ver el navegador haciendo su trabajo o no. Cuando se construye el código es bueno tenerlo Visible = True
, pero cuando el código está funcionando para extraer datos es bueno no verlo cada vez Visible = False
.
With appIE
.Navigate "http://uk.investing.com/rates-bonds/financial-futures"
.Visible = True
End With
3) La página web necesitará algo de tiempo para cargarse. Así que esperaré mientras esté ocupado...
Do While appIE.Busy
DoEvents
Loop
4) Bueno, ahora la página está cargada. Digamos que quiero eliminar el cambio del T-Bond US30Y: Lo que haré será simplemente hacer clic en F12 en Internet Explorer para ver el código de la página web y, por lo tanto, usando el puntero (en el círculo rojo), haré clic en el elemento que Quiero raspar para ver cómo puedo alcanzar mi propósito.
5) Lo que debo hacer es sencillo. En primer lugar, obtendré mediante la propiedad ID el tr
elemento que contiene el valor:
Set allRowOfData = appIE.document.getElementById("pair_8907")
Aquí obtendré una colección de td
elementos (específicamente, tr
es una fila de datos y td
sus celdas. Estamos buscando el octavo, así que escribiré:
Dim myValue As String: myValue = allRowOfData.Cells(7).innerHTML
¿Por qué escribí 7 en lugar de 8? Debido a que las colecciones de celdas comienzan desde 0, el índice del octavo elemento es 7 (8-1). Analizando brevemente esta línea de código:
.Cells()
me hace acceder a lostd
elementos;innerHTML
es propiedad de la celda que contiene el valor que buscamos.
Una vez que tengamos nuestro valor, que ahora está almacenado en la myValue
variable, podemos simplemente cerrar el navegador IE y liberar la memoria configurándolo en Nada:
appIE.Quit
Set appIE = Nothing
Bueno, ahora tienes tu valor y puedes hacer lo que quieras con él: ponerlo en una celda ( Range("A1").Value = myValue
), o en la etiqueta de un formulario ( Me.label1.Text = myValue
).
Solo me gustaría señalarle que no es así como funciona StackOverflow: aquí publica preguntas sobre problemas de codificación específicos, pero primero debe realizar su propia búsqueda. La razón por la que respondo una pregunta que no demuestra demasiado esfuerzo de investigación es simplemente porque veo que me la han hecho varias veces y, volviendo a la época en que aprendí a hacer esto, recuerdo que me hubiera gustado tener algunas mejores. soporte para comenzar. Así que espero que esta respuesta, que es solo un "aporte de estudio" y no es en absoluto la mejor/más completa solución, pueda ser de apoyo para el próximo usuario que tenga el mismo problema. Porque he aprendido a programar gracias a esta comunidad y me gusta pensar que tú y otros principiantes podrían utilizar mis aportes para descubrir el hermoso mundo de la programación.
Disfruta tu práctica ;)
Se mencionaron otros métodos, así que reconozcamos que, en el momento de escribir este artículo, estamos en el siglo XXI. Estacionemos la apertura del navegador del bus local y volemos con una solicitud XMLHTTP GET (XHR GET para abreviar).
Momento Wiki:
XHR es una API en forma de objeto cuyos métodos transfieren datos entre un navegador web y un servidor web. El objeto es proporcionado por el entorno JavaScript del navegador.
Es un método rápido para recuperar datos que no requiere abrir un navegador. La respuesta del servidor se puede leer en un HTMLDocument y el proceso de captura de la tabla continúa desde allí.
Tenga en cuenta que el contenido renderizado/agregado dinámicamente de JavaScript no se recuperará ya que no hay ningún motor de JavaScript en ejecución (que sí existe en un navegador).
En el siguiente código, la tabla se toma por su identificación cr1
.
En el subayudante, WriteTable
recorremos las columnas ( td
etiquetas) y luego las filas de la tabla ( tr
etiquetas), y finalmente recorremos la longitud de cada fila de la tabla, celda por celda de la tabla. Como solo queremos datos de las columnas 1 y 8, Select Case
se utiliza una declaración para especificar lo que se escribe en la hoja.
Vista de página web de muestra:
Salida de código de muestra:
VBA:
Option Explicit
Public Sub GetRates()
Dim html As HTMLDocument, hTable As HTMLTable '<== Tools > References > Microsoft HTML Object Library
Set html = New HTMLDocument
With CreateObject("MSXML2.XMLHTTP")
.Open "GET", "https://uk.investing.com/rates-bonds/financial-futures", False
.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" 'to deal with potential caching
.send
html.body.innerHTML = .responseText
End With
Application.ScreenUpdating = False
Set hTable = html.getElementById("cr1")
WriteTable hTable, 1, ThisWorkbook.Worksheets("Sheet1")
Application.ScreenUpdating = True
End Sub
Public Sub WriteTable(ByVal hTable As HTMLTable, Optional ByVal startRow As Long = 1, Optional ByVal ws As Worksheet)
Dim tSection As Object, tRow As Object, tCell As Object, tr As Object, td As Object, r As Long, C As Long, tBody As Object
r = startRow: If ws Is Nothing Then Set ws = ActiveSheet
With ws
Dim headers As Object, header As Object, columnCounter As Long
Set headers = hTable.getElementsByTagName("th")
For Each header In headers
columnCounter = columnCounter + 1
Select Case columnCounter
Case 2
.Cells(startRow, 1) = header.innerText
Case 8
.Cells(startRow, 2) = header.innerText
End Select
Next header
startRow = startRow + 1
Set tBody = hTable.getElementsByTagName("tbody")
For Each tSection In tBody
Set tRow = tSection.getElementsByTagName("tr")
For Each tr In tRow
r = r + 1
Set tCell = tr.getElementsByTagName("td")
C = 1
For Each td In tCell
Select Case C
Case 2
.Cells(r, 1).Value = td.innerText
Case 8
.Cells(r, 2).Value = td.innerText
End Select
C = C + 1
Next td
Next tr
Next tSection
End With
End Sub
puede usar el objeto winhttprequest en lugar de Internet Explorer, ya que es bueno cargar datos excluyendo imágenes y anuncios en lugar de descargar una página web completa que incluya anuncios e imágenes que hacen que el objeto de Internet Explorer sea pesado en comparación con el objeto winhttpRequest.
Esta pregunta se hizo mucho antes. Pero pensé que la siguiente información será útil para los novatos. En realidad, puedes obtener fácilmente los valores del nombre de la clase como este.
Sub ExtractLastValue()
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Top = 0
objIE.Left = 0
objIE.Width = 800
objIE.Height = 600
objIE.Visible = True
objIE.Navigate ("https://uk.investing.com/rates-bonds/financial-futures/")
Do
DoEvents
Loop Until objIE.readystate = 4
MsgBox objIE.document.getElementsByClassName("pid-8907-last")(0).innerText
End Sub
Y si eres nuevo en el web scraping, lee esta publicación de blog.
Web Scraping: conceptos básicos
Y también existen diversas técnicas para extraer datos de páginas web. Este artículo explica algunos de ellos con ejemplos.
Web Scraping: recopilación de datos de una página web