Я пытаюсь очистить данные сайта с помощью Excel VBA - PullRequest
0 голосов
/ 27 октября 2018

Итак, я начну с того, что я очень новичок в VBA.Я пытаюсь извлечь данные из таблицы на этой странице .Я не сделал ничего особенного в том, что касается кода, так что будь проще для меня.Я ищу какое-то руководство о том, как подойти к нему и можно ли это сделать, что, я полагаю, можно.Если кто-нибудь сможет помочь мне направить меня в правильном направлении, это будет очень цениться.

Sub rgnbateamstats()

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


With appIE
.navigate "https://rotogrinders.com/team-stats/nba-earned?site=draftkings"
.Visible = True
End With

Do While appIE.Busy
DoEvents
Loop

Set allRowOfData = appIE.document.getElementById("proj-stats")

Не совсем уверен, куда идти дальше или я даже на правильном пути.

Ответы [ 3 ]

0 голосов
/ 27 октября 2018

Это займет всю таблицу на этой странице.

В этом проекте используется раннее связывание . Вам необходимо установить ссылки на:

  • Microsoft Internet Controls
  • Библиотека объектов Microsoft HTML

Вы можете сделать это в VBE> Инструменты> Ссылки.

Скажу, этот сайт использует очень странный метод настройки своих таблиц, и было интересно найти приличный способ сделать это.

Также еще одна вещь, с которой вы можете или не можете согласиться, это то, что в этой таблице есть скрытые столбцы, которые не отображаются на сайте, но будут отображаться в вашем документе Excel. Если вы не согласны с этим, вы можете просто удалить или скрыть их после выполнения этого кода - или, если вы хотите изменить это, чтобы предотвратить это во время выполнения, вы получите больше энергии.

Option Explicit

Sub rgnbateamstats()

    Const url$ = "https://rotogrinders.com/team-stats/nba-earned?site=draftkings"

    Dim IE As New InternetExplorer, doc As HTMLDocument
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets(1)

    With IE
        .Navigate url
        .Visible = True
        ieBusy IE
        Set doc = .Document
    End With

    Dim r As Long, c As Long, tCol As HTMLDivELement
    Dim subTbls(): subTbls = Array("rgt-bdy left", "rgt-bdy mid", "rgt-bdy right")

    Dim subTbl As Long        
    For subTbl = 0 To 2
        For Each tCol In getSubTblCols(doc, subTbls(subTbl)).getElementsByClassName("rgt-col")
            c = c + 1
            For r = 1 To tCol.getElementsByTagName("div").Length
                ws.Cells(r, c) = tCol.getElementsByTagName("div")(r - 1).innerText
            Next
        Next tCol
    Next subTbl

End Sub

Private Function getSubTblCols(doc As HTMLDocument, ByVal className$) As HTMLDivElement
    Dim tbl As HTMLTable
    Set tbl = doc.getElementById("proj-stats")
    Set getSubTblCols = tbl.getElementsByClassName(className)(0).Children(0). _
            Children(1)
End Function

Private Sub ieBusy(ieObj As InternetExplorer)
    With ieObj
        Do While .Busy Or .ReadyState < READYSTATE_COMPLETE
            DoEvents
        Loop
    End With
End Sub

Ладно, пора попробовать что здесь происходит.

В вашей таблице есть три вложенных таблицы. Это лучший способ объяснить это, но это означает, что вы сначала пройдете по каждой подстоле с помощью следующей строки:

For subTbl = 0 To 2

В этом цикле вы будете зацикливать столбцы этой вложенной таблицы с помощью следующей строки:

For Each tCol In getSubTblCols(doc, subTbls(subTbl)).getElementsByClassName("rgt-col")

rgt-col - это имя класса для столбца в каждой таблице - так что, по крайней мере, эта часть была легкой. Функция getSubTblCols захватывает имя класса основного элемента вложенной таблицы одного из трех имен вложенной таблицы в массиве subTbls().

c - ваш номер столбца Excel, r - номер строки. Вы также используете r для каждого номера строки HTML, но он использует base 0, поэтому вам нужно вычесть 1.

Затем получите значение ячейки, используя свойство innerText ячейки, поместите его в электронную таблицу, затем промойте и повторите.

Я переместил функцию занятой веб-страницы на новый саб, ieBusy. Я также добавил свойство .readyState, потому что, как я сказал в моем комментарии , само по себе .busy ненадежно в лучшем случае.

0 голосов
/ 27 октября 2018

Несмотря на то, что раскладка стола может показаться немного странной, на самом деле ей нужно всего лишь 180 мыслей. Вы можете получить столбцы по имени класса, а затем просто зациклить строки; вместо обычного зацикливания строк, а затем столбцов.

Я использую Селектор класса CSS , чтобы захватить столбцы с помощью querySelectorAll, т.е. я нацеливаю столбцы по имени класса. Это возвращает nodeList, содержащий каждый из столбцов. Ниже приведен пример первых двух столбцов (по общему признанию, abbr не виден). Каждая строка в столбце находится в div, поэтому, если я зациклю столбцы, я получу строки в каждом столбце, захватив соответствующую коллекцию тегов div. Тогда я просто зацикливаю эти записи.

enter image description here

Option Explicit
Public Sub GetInfo()
    Dim IE As New InternetExplorer, iColumns As Object, iRow As Object, i As Long, j As Long, r As Long, c As Long
    Application.ScreenUpdating = False
    With IE
        .Visible = True
        .navigate "https://rotogrinders.com/team-stats/nba-earned?site=draftkings"

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

        Set iColumns = .document.querySelectorAll(".rgt-col")

        With ThisWorkbook.Worksheets("Sheet1")
            For i = 0 To iColumns.Length - 1
                c = c + 1: r = 0
                Set iRow = iColumns.item(i).getElementsByTagName("div")
                For j = 0 To iRow.Length - 1
                    r = r + 1
                    .Cells(r, c) = iRow(j).innerText
                Next
            Next
        End With
        Application.ScreenUpdating = True
        .Quit
    End With
End Sub

Ссылки

VBA> Инструменты> Справочные материалы> Microsoft Internet Controls

Или изменить на позднюю привязку с:

Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
0 голосов
/ 27 октября 2018

Попробуйте эту часть для извлечения первого столбца

Set allrowofdata = appIE.document.getElementById("proj-stats")

Set newobj = allrowofdata.getElementsByClassName("rgt-col")(0)

For Each x In newobj.Children
r = r + 1
Cells(r, 1).value = x.innerText
Next x
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...