【问题标题】:Parsing HTML getElementsByTagName not returning all cells解析 HTML getElementsByTagName 不返回所有单元格
【发布时间】:2019-08-12 09:44:17
【问题描述】:

我有一些代码可用于从网页中抓取数据,但网页已更改,无法再使其正常工作。该代码应该对内部事务表进行计算,但是getelementsbytagname("td") 不再返回所有单元格。

我猜这是因为它是嵌入在页面或其他东西中的页面,但我无法终生解决它,我对 html 不是很熟悉。一个示例网页是gurufocus.com/stock/lmb/insider

我的代码如下:

Sub getStatements()
    Dim wb As Object
    Dim doc As Object
    Dim incomeStmtURLs As Variant
    Dim sURL As String
    Dim allCells As IHTMLElementCollection
    Dim aCell As HTMLTableCell
    Dim i As Integer
    Dim loginBoxData As String    

    Application.DisplayAlerts = False

    Call ToggleEvents(False)

    incomeStmtURLs = Range("Sheet1!h1:h2").Value

    For i = 1 To UBound(incomeStmtURLs)
        Set wb = CreateObject("internetExplorer.Application")
        sURL = incomeStmtURLs(i, 1)

        wb.navigate sURL
        wb.Visible = False

        While wb.Busy
            Application.Wait Now + #12:00:01 AM#
            DoEvents
        Wend

        'HTML document
        Set doc = wb.document

        On Error GoTo err_clear

        ' gets all cell and looks for date format,
        ' goes from new transaction to old so once gets to older than a year it exits for loop
        ' checks nextSibling from date is a buy and if so does calculations, by taking further value sin row
        ' for priceThisTime have to get rid of $ symbol for calculation
        Set allCells = doc.getElementsByTagName("td")
        For Each aCell In allCells
            MsgBox (aCell.innerText)
            If aCell.innerText Like "####-##-##" = True Then
                If CDate(aCell.innerText) >= Date - 365 Then
                    If aCell.NextSibling.innerText = "Buy" Then
                        buys = buys + 1
                        sharesThisTime = CDec(aCell.NextSibling.NextSibling.innerText)
                        priceThisTime = aCell.NextSibling.NextSibling.NextSibling.NextSibling.innerText
                        totalPrice = totalPrice + (sharesThisTime * CDec(Right(priceThisTime, Len(priceThisTime) - 1)))
                        shareCount = shareCount + sharesThisTime
                    End If
                Else
                    Exit For
                End If
            End If
        Next aCell

        Sheet6.Cells(i + 1, 2) = buys
        If (shareCount <> 0) Then
            Sheet6.Cells(i + 1, 3).Value = totalPrice / shareCount
        End If

        buys = 0
        totalPrice = 0
        shareCount = 0

err_clear:
        If Err <> 0 Then
            Err.Clear
            Resume Next
        End If
        wb.Quit
    Next i

    Call ToggleEvents(True)
End Sub

【问题讨论】:

    标签: html excel vba web-scraping getelementsbytagname


    【解决方案1】:

    以下内容专门针对该表并检索所有 td 元素。我认为您的逻辑可能可以基于列号应用,但无论如何(以防万一我也将表设置为变量)。

    我将每页的结果设置为 100,但您可以注释掉该行

    Option Explicit
    'VBE > Tools > References:
    ' Microsoft Internet Controls
    
    Public Sub GetData()
        Dim ie As New InternetExplorer, lastDropDrownItemIndex As Long, dropDown As Object, t As Date
        Const MAX_WAIT_SEC As Long = 10
    
    
        With ie
            .Visible = True
            .Navigate2 "https://www.gurufocus.com/stock/lmb/insider"
    
            While .Busy Or .readyState < 4: DoEvents: Wend
            t = Timer
    
            Do
                Set dropDown = .document.querySelectorAll(".el-dropdown-menu__item")
                lastDropDrownItemIndex = dropDown.Length - 1
                If Timer - t > MAX_WAIT_SEC Then Exit Do
            Loop While lastDropDrownItemIndex < 1
    
            If dropDown.Length = 0 Then Exit Sub
    
            dropDown.item(lastDropDrownItemIndex).Click 'comment me out if don't want 100 results per page
    
            Dim tds As Object, table As Object
            Set tds = .document.getElementsByClassName("data-table")(0).getElementsByTagName("td")
            Set table = .document.getElementsByClassName("data-table")
            Stop
            .Quit
        End With
    End Sub
    

    【讨论】:

    • 告诉我这是怎么回事
    • 这太棒了,谢谢。我不知道该表被称为“数据表”,我之前一直试图将其称为“普通表数据表”。您可以看到为什么我认为查看 html !当涉及到这些东西时,我很无知。您还解决了我的下一个问题,将表格更改为 100 行。谢谢。
    • 我不完全理解,但有时它会卡在 Do 循环中虽然您为下拉菜单所做的那样,但 lastDropDownItemIndex 的值似乎始终为 11 但是如果我使用 dropDown.item(11 ).click 这不起作用。你知道解决这个问题的方法吗?再次感谢。
    • 我认为由于某种原因该表没有加载。我添加了一个超时,这样如果 10 秒后没有加载程序将安全退出。当页面卡住时,您需要探索页面上发生的事情。我以为总是有一张桌子。
    • 如果你能找到一种方法让我复制问题,我会从头开始调试。
    猜你喜欢
    • 1970-01-01
    • 2013-03-21
    • 2013-07-15
    • 2019-03-04
    • 1970-01-01
    • 2023-03-24
    • 2013-09-20
    • 2013-10-19
    • 1970-01-01
    相关资源
    最近更新 更多