Descargar tabla html con vba excel

6 envíos / 0 nuevos
Último envío
Javier88
Imagen de Javier88
Offline
última acción: Hace 5 años 7 meses
alta: 06/02/2018 - 09:13
Puntos: 70
Descargar tabla html con vba excel

Hola a todos y gracias de antemano.

Estoy intentando descargar una tabla a excel de la página mismarcadores.com.

He conseguido una macro por internet. El problema es que la etiqueta html de la tabla no tiene ID, y siempre que ejecuto la macro salta el siguiente error:

Se ha producido el error 438 en tiempo de ejecución: El objeto no admite esta propiedad o método

La macro que ejecuto es la siguiente:

 

Sub importartblhtml()
    Dim appIE As Object
    Dim allRowOfData As Object
    Dim curHTMLRow As Object
    Dim Fila As Long, Col As Long
    Dim Celda As Object
    Set appIE = CreateObject("internetexplorer.application")
    With appIE
        .Visible = True
        .navigate "https://www.mismarcadores.com/futbol/espana/laliga/partidos/"
        While .Busy = True Or .readyState < 4: DoEvents: Wend
     ThisWorkbook.Sheets("Hoja1").Activate
     Cells.Select
     Selection.ClearContents 'limpiamos contenidos 
        Set allRowOfData = appIE.document.getElementsById("fs-fixtures")
        For Fila = 1 To allRowOfData.Rows.Length - 1
            Set curHTMLRow = allRowOfData.Rows(Fila)
            For Col = 0 To curHTMLRow.Cells.Length - 1
                Set Celda = Sheets("Hoja1").Cells(Fila + 1, Col + 1)
                Celda.Value = "'" & curHTMLRow.Cells(Col).innerText
            Next Col
        Next Fila
        .Quit
    End With
    Set appIE = Nothing
    Set curHTMLRow = Nothing
    Set Celda = Nothing
End Sub

El error salta al ejecutarse la línea Set allRowOfData = appIE.document.getElementsById("")
He probado con el método getElementsByTag("table")(0) y tampo funciona. Importa toda la página excepto lo que quiero, que son los partidos.
No he encontrado mucha información por internet hacerca de como solucionar el error.
El código html de donde quiero sacar los datos es el siguiente
















Alguien sabe si me falta activar alguna referencia o algún otro método para poder descargar esta tabla??
Gracias.
Saludos.

Etiquetas: 

Cron
Imagen de Cron
Offline
última acción: Hace 8 meses 2 días
Nivel 1 - 200 puntosNivel 2 - 500 puntosNivel 3 - 1000 puntosNivel 4 - 2000 puntosNivel 5 - 4000 puntos
alta: 23/06/2010 - 12:30
Puntos: 12735
Prueba a sustituir

Prueba a sustituir "getElementsById" por "getElementById"

Parece que te sobra una s. Ten en cuenta que en HTML solo puede haber un elemento con una ID en una página, de ahí el singular. En el resto de opciones (class, tag, etc.) puede haber todos los elementos que quieras.

 

Lo que pasa es que después seguirás teniendo problemas.

Tu segundo problema es que el objeto allRowOfData, tal como lo tienes definido, es un <div>. Por eso no tiene propiedad rows. Lo que tienes que hacer es seleccionar el child del objeto que tenemos identificado con un <id>, que sí que es un objeto tabla, y eso lo hacemos así:

        Set allRowOfData = appIE.document.getElementById("fs-fixtures").LastChild
En nuestro caso nos vale "LastChild" porque como el div solo tiene dentro la tabla, pues es el último. Si no, tendríamos que seleccionar el adecuado, por ejemplo poniendo .all(5) en vez de .LastChild en caso de que fuese el quinto elemento.
 
Por lo tanto, si sustituyes tu línea por la que te he puesto al final, te funcionará correctamente para la página web que estás revisando.
 
Un saludo
Javier88
Imagen de Javier88
Offline
última acción: Hace 5 años 7 meses
alta: 06/02/2018 - 09:13
Puntos: 70
Hola Cron.Muchas gracias por

Hola Cron.

Muchas gracias por tu respuesta, funciona perfectamente.

Siento haber tardado en contestar, pero estaba trabajando.

No quisisera abusar, pero al final de la tabla, hay un link que sirve para mostrar más partidos.

Sabrias como activarlo mediante vba??

yo he encontrado este código

Do Until link = "Mostrar más partidos"
                i = i + 1
                p = appIE.Document.Links(i).tostring
                link = Right(p, 20)
            Loop
        appIE.Document.Links(i).Click

y algún otro parecido, pero no consigo hacerlo funcionar.

Gracias.

Saludos.

Cron
Imagen de Cron
Offline
última acción: Hace 8 meses 2 días
Nivel 1 - 200 puntosNivel 2 - 500 puntosNivel 3 - 1000 puntosNivel 4 - 2000 puntosNivel 5 - 4000 puntos
alta: 23/06/2010 - 12:30
Puntos: 12735
Por cómo funciona, deberías

Por cómo funciona, deberías hacer click siempre que aparezca "Mostrar más partidos" antes de empezar el volcado de la tabla. El código sería algo así como:

    flag = false
    Do while flag = false
        For Each allRowOfData In .document.getElementsByTagName("a")
            If allRowOfData.outertext = "Mostrar más partidos" Then
                allRowOfData.Click
                flag = false
                Exit For
            else
                 flag = true
            End If
        Next
    Loop

He utilizado allRowOfData como variable porque ya estaba declarada como object, por pura vagancia.

Este código se ejecuta una y otra vez hasta que recorre toda la hoja y no encuentra ningún link que diga "Mostrar más partidos". Como cada vez que hace click tarda en cargar, le falta la línea de while appIE.busy bla bla bla. Yo la pondría justo detrás del Do while.

Un saludo

Javier88
Imagen de Javier88
Offline
última acción: Hace 5 años 7 meses
alta: 06/02/2018 - 09:13
Puntos: 70
Gracias Cron.El problema es

Gracias Cron.

El problema es que el código no reconoce cuando ese link está oculto, y sigue activandolo aun cuando la tabla de los partidos está completa.

Seguire investigando como solucionar eso.

Muchas gracias.

Cron
Imagen de Cron
Offline
última acción: Hace 8 meses 2 días
Nivel 1 - 200 puntosNivel 2 - 500 puntosNivel 3 - 1000 puntosNivel 4 - 2000 puntosNivel 5 - 4000 puntos
alta: 23/06/2010 - 12:30
Puntos: 12735
Qué interesante!!Si miras el

Qué interesante!!

Si miras el código de la página web, verás que el link <a> está dentro de una tabla (un <td> dentro de un <tr> que, a su vez, está dentro de un <table>.

Para hacer que el enlace se muestre o no, simplemente le añaden al código del objeto <table> un código CSS inline así:

style:"display: none;"

Lo que tenemos que hacer es localizar esta tabla (igual que la tabla anterior, esta también tiene una id (tournament-page-fixtures-more), por lo que definiremos dos variables tipo objeto, una para el link y la otra para la tabla exterior. Además, he comprobado que al darle al link lo que produce es una actualización javascript, por lo que no genera un cambio de estado ni en la propiedad busy ni en la propiedad readyState del objeto appIE, por lo que tenemos que hacer una ñapa y decirle a Excel que espere 5 segundos antes de volver a hacer click. Finalmente, el código puede quedar así:

Sub importartblhtml()

    Dim appIE As Object

    Dim allRowOfData As Object

    Dim curHTMLRow As Object

    Dim Fila As Long, Col As Long

    Dim Celda As Object

    Dim flag As Boolean

    Set appIE = CreateObject("internetexplorer.application")

    Dim link As Object

    Dim parentLink As Object

    With appIE

        .Visible = True

        .navigate "https://www.mismarcadores.com/futbol/espana/laliga/partidos/"

        While .Busy = True Or .readyState < 4: DoEvents: Wend

     ThisWorkbook.Sheets("Hoja1").Activate

     Cells.Select

     Selection.ClearContents 'limpiamos contenidos

    

    flag = False

    Do While flag = False

        Set parentLink = appIE.document.getElementById("tournament-page-fixtures-more")   'la tabla que contiene el enlace

        If InStr(parentLink.outerhtml, "display: none;") = 0 Then    'Si no encuentra display: none;

            For Each link In .document.getElementsByTagName("a")    'Vuelvo a recorrer todos los links. Se podía hacer buscando el lastchild de parentLink, y seguramente sería mejor solución.

                If (link.outertext = "Mostrar más partidos") Then

                    Application.Wait (Now + TimeValue("0:00:05"))

                    link.Click

                    flag = False

                    Exit For

                Else

                     flag = True    'En caso de que no exista el link

                End If

            Next

        Else

            flag = True    'En caso de que el link exista, pero dentro de una tabla con style:"display: none;"

        End If

    Loop

        Set allRowOfData = appIE.document.getElementById("fs-fixtures").LastChild

        For Fila = 1 To allRowOfData.Rows.Length - 1

            Set curHTMLRow = allRowOfData.Rows(Fila)

            For Col = 0 To curHTMLRow.Cells.Length - 1

                Set Celda = Sheets("Hoja1").Cells(Fila + 1, Col + 1)

                Celda.Value = "'" & curHTMLRow.Cells(Col).innerText

            Next Col

        Next Fila

        .Quit

    End With

    Set appIE = Nothing

    Set curHTMLRow = Nothing

    Set Celda = Nothing

End Sub

 

 

Un saludo