scraping macro html excel vba excel-vba web-scraping

html - macro - Raspado de datos del sitio web usando vba



web scraping excel (5)

Esta pregunta se hizo mucho antes. Pero pensé que la siguiente información será útil para los novatos. En realidad, puede 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 raspado web, lee esta publicación de blog.

Web Scraping - Conceptos básicos

Y también hay varias 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

Estoy tratando de obtener datos del sitio web: http://uk.investing.com/rates-bonds/financial-futures través de vba, como el precio en tiempo real, es decir, alemán 5 YR Bobl, US 30Y T-Bond, he intentado sobresalir consulta web pero solo raspa todo el sitio web, pero me gustaría raspar solo la tasa, ¿hay alguna manera de hacerlo?


Hay varias maneras de hacer esto. Esta es una respuesta que escribo con la esperanza de que todos los conceptos básicos de la automatización de Internet Explorer se encuentren al buscar las palabras clave "raspar datos del sitio web", pero recuerde que nada vale como su propia investigación (si no desea apegarse a códigos preescritos que no puede 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 eso es bueno para entender la lógica detrás de la automatización de Internet.

1) Si necesito navegar por la web, ¡necesito un navegador! Entonces creo un navegador de Internet Explorer:

Dim appIE As Object Set appIE = CreateObject("internetexplorer.application")

2) Le pido al navegador que explore 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 compilar el código es bueno tener Visible = True , pero cuando el código está funcionando para raspar datos es bueno no verlo todo el tiempo, entonces 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. Entonces, 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 US30Y T-Bond: lo que haré es simplemente hacer clic en F12 en Internet Explorer para ver el código de la página web y, por lo tanto, usar el puntero (en 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é por la propiedad ID el elemento tr que contiene el valor:

Set allRowOfData = appIE.document.getElementById("pair_8907")

Aquí obtendré una colección de elementos td (específicamente, tr es una fila de datos, y td son 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? Como 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 los elementos td ;
  • innerHTML es la propiedad de la celda que contiene el valor que buscamos.

Una vez que tenemos nuestro valor, que ahora está almacenado en la variable myValue , podemos cerrar el navegador IE y liberar la memoria configurándolo en Nothing:

appIE.Quit Set appIE = Nothing

Bueno, ahora tiene su valor y puede hacer lo que quiera con él: ponerlo en una celda ( Range("A1").Value = myValue ), o en una etiqueta de un formulario ( Me.label1.Text = myValue )

Solo me gustaría señalarle que no es así como funciona : aquí publica preguntas sobre problemas de codificación específicos, pero primero debe hacer su propia búsqueda. La razón por la que estoy respondiendo una pregunta que no muestra demasiado esfuerzo de investigación es simplemente porque la veo varias veces y, cuando aprendí a hacer esto, recuerdo que me hubiera gustado tener algo mejor soporte para comenzar. Así que espero que esta respuesta, que es solo una "entrada de estudio" y no sea la mejor / más completa solución, pueda ser un soporte para el próximo usuario que tenga su mismo problema. Porque aprendí a programar gracias a esta comunidad y me gusta pensar que tú y otros principiantes podrían usar mi opinión para descubrir el hermoso mundo de la programación.

Disfruta tu práctica;)


Modifiqué algo que estaba apareciendo un error y terminé con esto, que funcionó muy bien para extraer los datos que necesitaba:

Sub get_data_web() Dim appIE As Object Set appIE = CreateObject("internetexplorer.application") With appIE .navigate "https://finance.yahoo.com/quote/NQ%3DF/futures?p=NQ%3DF" .Visible = True End With Do While appIE.Busy DoEvents Loop Set allRowofData = appIE.document.getElementsByClassName("Ta(end) BdT Bdc($c-fuji-grey-c) H(36px)") Dim i As Long Dim myValue As String Count = 1 For Each itm In allRowofData For i = 0 To 4 myValue = itm.Cells(i).innerText ActiveSheet.Cells(Count, i + 1).Value = myValue Next Count = Count + 1 Next appIE.Quit Set appIE = Nothing End Sub


Se mencionaron otros métodos, así que reconozcamos que, al momento de escribir, estamos en el siglo XXI. Estacionemos la apertura del navegador del bus local y vuele con una solicitud XMLHTTP GET (XHR GET para abreviar).

Momento Wiki:

XHR es una API en forma de un objeto cuyos métodos transfieren datos entre un navegador web y un servidor web. El objeto lo proporciona 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 capturar la tabla continuó desde allí.

En el siguiente código, la tabla es cr1 por su id cr1 .

En el sub auxiliar, WriteTable , hacemos un bucle de las columnas (etiquetas td ) y luego las filas de la tabla (etiquetas tr ), y finalmente atravesamos la longitud de cada fila de la tabla, celda de tabla por celda de tabla. Como solo queremos datos de las columnas 1 y 8, se utiliza una instrucción Select Case para especificar qué se escribe en la hoja.

Vista de la 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 publicidad en lugar de descargar la página web completa, incluyendo publicidad y fotos que hacen que el objeto de Internet Explorer sea pesado en comparación con el objeto winhttpRequest.