【问题标题】:Need help getting table from HTML需要帮助从 HTML 获取表格
【发布时间】:2018-11-14 21:15:33
【问题描述】:

我已使用以下代码从 Marketwatch.com 成功提取共同基金业绩数据:

Dim A As Long
Dim B As Long
Dim C As Long
Dim Z As Long


For Z = 1 To 35

    Range("A1").Select
    ActiveCell.Offset((37 + (Z * 10)), 0).Select
    If ActiveCell.Value = "" Then
    Exit For
    Else
    End If
Dim oHTML       As Object
Dim oTable      As Object
Dim x           As Long
Dim Y           As Long
Dim vData       As Variant

Set oHTML = CreateObject("HTMLFile")

With CreateObject("WinHTTP.WinHTTPRequest.5.1")
.Open "GET", "http://www.marketwatch.com/investing/fund/vfinx", False
.send
oHTML.body.innerhtml = .responsetext
End With

For Each oTable In oHTML.Getelementsbytagname("table")
If oTable.classname = "fundstable" Then
    ReDim vData(1 To oTable.Rows.Length, 1 To oTable.Rows(1).Cells.Length)

        For x = 1 To UBound(vData)
        For Y = 1 To UBound(vData, 2)
            vData(x, Y) = oTable.Rows(x - 1).Cells(Y - 1).innertext
        Next Y
        Next x

    With ActiveCell.Offset(1, 0)
    .Resize(UBound(vData), UBound(vData, 2)).Value = vData
    End With
Exit For
End If
Next oTable

Next Z

不幸的是,Marketwatch 添加了验证码来阻止机器人(即我)抓取他们的数据。我对此一无所知,所以我想我会尝试另一个网站。

我看了晨星:http://performance.morningstar.com/fund/performance-return.action?t=VFINX&region=usa&culture=en_US

看来我想要在该页面上的表格是:“table.r_table3 width955px print97”或只是“r_table3 width955px print97”,但似乎都不适合我。

有什么想法吗?

谢谢!

【问题讨论】:

    标签: html excel vba web-scraping


    【解决方案1】:

    数据由 javascript 加载,无法通过 XMLHTTP 请求获得,因为脚本不会运行来加载内容。

    例如,您可以将第二个链接用于 IE,并引入等待以确保加载信息。我展示了在索引 1 处获取具有该类名称的表。您可以在此处更改索引:

    ele.item(1).outerHTML
    

    因此,对于下一张表,请使用 clipboard.SetText ele.item(2).outerHTML。

    您还可以循环使用ele 的.Length 来获取每个表格,但请确保在粘贴时写入不同的单元格:

    Dim i As Long
    For i = 0 To ele.Length-1
        clipboard.SetText  ele.item(i).outerHTML
       'Etc   
    Next
    

    VBA:

    Option Explicit
    
    Public Sub GetInfo()
        Dim IE As New InternetExplorer, clipboard As Object
        Dim ele As Object, ws As Worksheet, t As Date, tableCount As Long
        Const MAX_WAIT_SEC As Long = 5
        Set ws = ThisWorkbook.Worksheets("Sheet1")
        Set clipboard = GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
    
        With IE
            .Visible = True
            .navigate "http://performance.morningstar.com/fund/performance-return.action?t=VFINX&region=usa&culture=en_US"
    
            While .Busy Or .readyState < 4: DoEvents: Wend
    
            With .document
                t = Timer
                Do
                    DoEvents
                    On Error Resume Next
                    Set ele = .querySelectorAll(".r_table3.print97")
                    tableCount = ele.Length
                    On Error GoTo 0
                    If Timer - t > MAX_WAIT_SEC Then Exit Do
                Loop While tableCount < 3
    
                If Not ele Is Nothing Then
                    clipboard.SetText ele.item(1).outerHTML
                    clipboard.PutInClipboard
                    ws.Cells(1, 1).PasteSpecial
                End If
            End With
            .Quit
        End With
    End Sub
    

    【讨论】:

    • 好的 - 工作正常 - 谢谢!但我实际上想在该页面上放下一张桌子。所以我将“.r_table3.print97”更改为“.r_table3.width955px.print97”,我开始收到运行时错误“424”:需要对象。请原谅我的新手问题,但我认为我们已经声明了该对象,所以我不明白为什么切换表会导致此错误。再次感谢您的帮助!
    • 使用剪贴板.SetText ele.item(2).outerHTML
    • 而不是clipboard.SetText ele.Item(1).outerHTML? (如果是这样,那对我不起作用)仍然出现相同的 424 错误
    • 如果你可以得到表 1,那么你应该能够得到下一个。在失败行之前插入 debug.print ele.length。然后 Ctrl + G 检查打印的值。另外,请检查您的代码是否与我上面的链接中的代码相同。您还可以增加 Const MAX_WAIT_SEC As Long = 10
    • 做到了!非常感谢你!!只有另一个问题 - 有什么方法可以在不打开窗户的情况下做到这一点?即只是在后台工作......我计划将此添加到其他代码中以在许多资金上拉出该表,并且不希望每次都打开一个新窗口。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2019-11-01
    • 2012-12-02
    • 1970-01-01
    • 2013-09-27
    • 2023-04-02
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多