1

I'm trying to scrape a table from the web but for some reason I'm not getting the entire table. It's only fetching 1 column instead of them all. Any help would be greatly appreciated! Thanks!

Here's my code:

Sub HistoricalData()

    Dim xmlHttp As Object
    Dim TR_col As Object, TR As Object
    Dim TD_col As Object, TD As Object
    Dim row As Long, col As Long

    Set xmlHttp = CreateObject("MSXML2.XMLHTTP.6.0")
    xmlHttp.Open "GET", "http://www.cnbc.com/bonds-canada-treasurys", False
    xmlHttp.setRequestHeader "Content-Type", "text/xml"
    xmlHttp.send

    Dim html As Object
    Set html = CreateObject("htmlfile")
    html.body.innerHTML = xmlHttp.responseText

    Dim tbl As Object
    Set tbl = html.getElementById("curr_table")

    row = 1
    col = 1

    Set TR_col = html.getElementsByTagName("TR")
    For Each TR In TR_col
        Set TD_col = TR.getElementsByTagName("TD")
        For Each TD In TD_col
            Cells(row, col) = TD.innerText
            col = col + 1
        Next
        col = 1
        row = row + 1
    Next
End Sub
6
  • what is TD_col.count on entry to the loop? Commented Dec 6, 2016 at 15:41
  • not sure, been using this code I found online to scrape a bunch of tables, nows the online time its not working. Commented Dec 6, 2016 at 15:43
  • @Nathan, do you know how to make this work? Commented Dec 6, 2016 at 16:12
  • See the source of the page. you are loading exactly the table in the source of the web page. The data are loaded from a datasource Commented Dec 6, 2016 at 16:47
  • @D.O. I'm a noob, can you explain this further? I clicked "inspect" but I dont see where the site is getting its data. Commented Dec 6, 2016 at 16:54

2 Answers 2

3

The problem is that you are getting the HTTP.responseText back before the page is finished loading.

I was unable to getMSXML2.XMLHTTP.6.0 to wait for the page to finish loading before returning the HTTP.responseText, so I switched to IE.

enter image description here

Sub HistoricalData()
    Const URL As String = "http://www.cnbc.com/bonds-canada-treasurys"
    Const READYSTATE_COMPLETE As Integer = 4
    Dim IE As Object
    Dim TR_col As Object, TR As Object
    Dim TD_col As Object, TD As Object
    Dim row As Long, col As Long

    Set IE = CreateObject("InternetExplorer.Application")

    IE.Navigate URL

    Do While (IE.Busy Or IE.ReadyState <> READYSTATE_COMPLETE)
        DoEvents
    Loop

    Set TR_col = IE.Document.getElementsByTagName("TR")

    For Each TR In TR_col
        Set TD_col = TR.getElementsByTagName("TD")

        For Each TD In TD_col
            Cells(row, col) = TD.innerText
            col = col + 1
        Next
        col = 1
        row = row + 1
    Next
End Sub
Sign up to request clarification or add additional context in comments.

1 Comment

@ryguy7272 Thanks :-). Did you see: Tim Williams answer to Object Vba read items?
0

A few years late, I know, but here's a much more elegant solution IMHO, which gives you more control over the data, in the hope that someone will find it useful sometime.

The problem is you are requesting the whole page, instead of just the data.

For this solution you will need to import VBA-JSON and add a reference to Microsoft Scripting Runtime

Sub cnbc()
Dim req As New WinHttpRequest
Dim reqURL As String
Dim respString As String
Dim respJSON As Object
Dim item As Object
Dim i As Long
Dim key As String
i = 1
reqURL = "https://quote.cnbc.com/quote-html-webservice/quote.htm?partnerId=2&requestMethod=quick&exthrs=1&noform=1&fund=1&output=jsonp&symbols=CA1M-CA|CA3M-CA|CA1Y-CA|CA3Y-CA|CA4Y-CA|CA5Y-CA|CA20Y-CA|CA30Y-CA&callback=quoteHandler1"
With req
    .Open "GET", reqURL, False
    .send
    respString = .responseText
End With
key = "quoteHandler1("
respString = Mid(respString, InStr(respString, key) + Len(key), Len(respString) - Len(key) - 1) 'extract the JSON string
Set respJSON = JsonConverter.ParseJson(respString) 'parse JSON string into something usable
For Each item In respJSON("QuickQuoteResult")("QuickQuote")
    ThisWorkbook.Worksheets(1).Cells(i, "A") = item("shortName")
    ThisWorkbook.Worksheets(1).Cells(i, "B") = item("last")
    ThisWorkbook.Worksheets(1).Cells(i, "C") = item("change")
    i = i + 1
Next item
End Sub

enter image description here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.