Comment puis-je extraire des données d'un site Web et remplir une feuille Excel à l'aide de VBA?


MA84

Je souhaite extraire des données de betexplorer.com. Je souhaite extraire deux données différentes de l'URL suivante:

https://www.betexplorer.com/soccer/s...eague-1/stats/

Je voudrais extraire les matchs joués et les matchs restants Je voudrais extraire les buts à domicile et à l'extérieur (par match)

J'ai le code pour le faire et c'est comme suit:

Option Explicit

Sub GetSoccerStats()


'Set a reference (VBE > Tools > References) to the following libraries:
'   1) Microsoft XML, v6.0
'   2) Microsoft HTML Object Library

Dim xmlReq As New MSXML2.XMLHTTP60
Dim objDoc As New MSHTML.HTMLDocument
Dim objTable As MSHTML.htmlTable
Dim objTableRow As MSHTML.htmlTableRow
Dim strURL As String
Dim strResp As String
Dim strText As String
Dim rw As Long

strURL = "https://www.betexplorer.com/soccer/south-korea/k-league-1/stats/"

With xmlReq
    .Open "GET", strURL, False
    .send
    If .Status <> 200 Then
        MsgBox "Error " & .Status & ":  " & .statusText
        Exit Sub
    End If
    strResp = .responseText
End With

Worksheets.Add

objDoc.body.innerHTML = strResp

Set objTable = objDoc.getElementsByClassName("table-main leaguestats")(0)

If Not objTable Is Nothing Then
    rw = 1
    For Each objTableRow In objTable.Rows
        strText = objTableRow.Cells(0).innerText
        Select Case strText
            Case "Matches played", "Matches remaining", "Home goals", "Away goals"
                Cells(rw, "a").Value = objTableRow.Cells(0).innerText
                Cells(rw, "b").Value = objTableRow.Cells(1).innerText
                Cells(rw, "c").Value = objTableRow.Cells(2).innerText
                rw = rw + 1
        End Select
    Next objTableRow
    Columns("a").AutoFit
End If

Set xmlReq = Nothing
Set objDoc = Nothing
Set objTable = Nothing
Set objTableRow = Nothing


End Sub

Ce code fonctionne mais je veux aller plus loin.

Je souhaite en fait exécuter cette macro pour de nombreuses URL différentes sur le même site. J'ai une feuille de calcul déjà créée qui contient une liste des ligues de football (dans les lignes), les colonnes contiennent les données.

Vous pouvez trouver le fichier ici: https://www.dropbox.com/s/77sol24sty75w5z/Avg%20Goals.xlsm?dl=0

Il s'agit d'un fichier dans lequel j'ajouterai des ligues aux lignes au fur et à mesure. Est-il possible d'adapter le code qui extrait les données pour qu'il puisse peupler les colonnes de ma feuille? Je n'ai pas besoin de saisir les noms des données (matchs restants, buts à domicile, buts à l'extérieur, etc.) comme le fait ce code, j'ai seulement besoin des chiffres. Les chiffres extraits devraient remplir les colonnes selon la feuille (de sorte que chaque ligne contient les données pour chaque ligue. Comme vous pouvez le voir, il y a quelques ligues, il faudrait donc parcourir chaque ligne, puis utiliser l'URL correspondante pour cela. rangée.

Vous remarquerez qu'il y a une colonne qui contient le mot ACTUEL. Cela indique qu'il doit utiliser l'URL dans la colonne URL actuelle. Si je change la valeur en LAST, je voudrais qu'il utilise l'URL dans la colonne Dernière URL.

Pour chaque ligue, ce sera différent si j'utilise CURRENT ou LAST.

Voici une image de la sortie attendue:

production attendue

Toute aide est grandement appréciée.

QHarr

Conformément à votre code, les données de ces éléments seront affichées dans les colonnes M: T. J'ai une fonction d'assistance GetLinks, qui génère un tableau d'URL finales à utiliser en fonction de la valeur de la colonne K:

inputArray = GetLinks(inputArray)

Ce tableau est en boucle et des requêtes xhr sont émises pour l'information. Toutes les informations sur les résultats sont stockées dans un tableau, resultsqui est écrit en une seule fois sur la feuille à la fin.

Je travaille avec un tableau tout au long car vous ne voulez pas continuer à lire à partir de la feuille; c'est une opération coûteuse qui ralentit votre code. Pour la même raison, si <> 200 se produit, j'imprime dans la fenêtre immédiate le message et l'url afin de ne pas ralentir le code. Vous avez effectivement un journal que vous pouvez consulter à la fin.

Les résultats récupérés sont écrits à partir de la colonne M, mais comme les données sont dans un tableau, vous pouvez facilement écrire là où vous le souhaitez; changez simplement la cellule de début pour coller à partir M4de la cellule la plus à gauche de votre choix. Vos colonnes existantes n'ont pas de pourcentages, donc je me sentais en sécurité pour supposer que vous vous attendiez à ce que les données écrites soient dans de nouvelles colonnes (peut-être même dans une feuille différente).

Option Explicit   
Public Sub GetSoccerStats()
    Dim xmlReq As New MSXML2.XMLHTTP60, response As String
    Dim objDoc As New MSHTML.HTMLDocument, text As String
    Dim lastRow As Long, dataSheet As Worksheet, inputArray(), i As Long

    Set dataSheet = ThisWorkbook.Worksheets("AVG GOAL DATA")

    With dataSheet
        lastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
    End With

    inputArray = dataSheet.Range("J4:L" & lastRow).Value
    inputArray = GetLinks(inputArray)

    Dim results(), r As Long, c As Long
    ReDim results(1 To UBound(inputArray, 1), 1 To 8)

    With xmlReq

        For i = LBound(inputArray, 1) To UBound(inputArray, 1)
            r = r + 1
            .Open "GET", inputArray(i, 4), False
            .send
            If .Status <> 200 Then
                Debug.Print inputArray(i, 4), vbTab, "Error " & .Status & ":  " & .statusText
            Else
                response = .responseText
                objDoc.body.innerHTML = response

                Dim objTable As MSHTML.HTMLTable, objTableRow As MSHTML.HTMLTableRow

                Set objTable = objDoc.getElementsByClassName("table-main leaguestats")(0)

                If Not objTable Is Nothing Then
                    c = 1
                    For Each objTableRow In objTable.Rows
                        text = objTableRow.Cells(0).innerText
                        Select Case text
                        Case "Matches played", "Matches remaining", "Home goals", "Away goals"
                            results(r, c) = objTableRow.Cells(1).innerText
                            results(r, c + 1) = objTableRow.Cells(2).innerText
                            c = c + 2
                        End Select
                    Next objTableRow
                End If
            End If
            Set objTable = Nothing
        Next
    End With
    dataSheet.Range("M4").Resize(UBound(results, 1), UBound(results, 2)) = results
End Sub

Public Function GetLinks(ByRef inputArray As Variant) As Variant
    Dim i As Long
    ReDim Preserve inputArray(1 To UBound(inputArray, 1), 1 To UBound(inputArray, 2) + 1)

    For i = LBound(inputArray, 1) To UBound(inputArray, 1)
        inputArray(i, 4) = IIf(inputArray(i, 1) = "CURRENT", inputArray(i, 2), inputArray(i, 3))
    Next
    GetLinks = inputArray
End Function

Disposition du fichier:

entrez la description de l'image ici


Étant donné le grand nombre de demandes qui ont entraîné un blocage, voici la version IE:

'VBE > Tools > References:
'1: Microsoft HTML Object library  2: Microsoft Internet Controls
Public Sub GetSoccerStats()
    Dim ie As Object, t As Date
    Dim objDoc As New MSHTML.HTMLDocument, text As String
    Dim lastRow As Long, dataSheet As Worksheet, inputArray(), i As Long

    Const MAX_WAIT_SEC As Long = 10

    Set dataSheet = ThisWorkbook.Worksheets("AVG GOAL DATA")
    Set ie = CreateObject("InternetExplorer.Application")
    With dataSheet
        lastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
    End With

    inputArray = dataSheet.Range("C4:E" & lastRow).Value
    inputArray = GetLinks(inputArray)

    Dim results(), r As Long, c As Long
    ReDim results(1 To UBound(inputArray, 1), 1 To 8)

    With ie
        .Visible = True
        For i = LBound(inputArray, 1) To UBound(inputArray, 1)
            r = r + 1
            .navigate2 inputArray(i, 4)

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

            Dim objTable As MSHTML.HTMLTable, objTableRow As MSHTML.HTMLTableRow
            t = timer
            Do
                DoEvents
                On Error Resume Next
                Set objTable = .document.getElementsByClassName("table-main leaguestats")(0)
                On Error GoTo 0
                If Timer - t > MAX_WAIT_SEC Then Exit Do
            Loop While objTable Is Nothing

            If Not objTable Is Nothing Then
                c = 1
                For Each objTableRow In objTable.Rows
                    text = objTableRow.Cells(0).innerText
                    Select Case text
                    Case "Matches played", "Matches remaining", "Home goals", "Away goals"
                        results(r, c) = objTableRow.Cells(1).innerText
                        results(r, c + 1) = objTableRow.Cells(2).innerText
                        c = c + 2
                    End Select
                Next objTableRow
            End If
            Set objTable = Nothing
        Next
        .Quit
    End With
    dataSheet.Range("F4").Resize(UBound(results, 1), UBound(results, 2)) = results
End Sub

Articles connexes


extraire des données tabulaires d'une feuille Excel à l'aide de r

Aakash Comment extraire des données tabulaires d'une feuille de calcul (qui contient également des données indésirables) à l'aide de R. cliquez pour afficher la feuille de calcul . je peux écrire ça en r- xcelfile<-read.xlsx("LT257-Refuel 3 March2017.xlsx",she