1

I have been trying to scrape and parse a website for some financial data so that I can add the data to an Excel spreadsheet using VBA. I have found several possible solutions, but I cannot seem to get them to fit my parameters. My problem is that I only need one variable (Average Target Price) from a table. I have not been able to figure out what I am doing wrong. I will also be using a similar VBA format to check several hundred companies at a time so if there is a more efficient way to code what I have please let me know.

Here is what I have so far:

Sub ImportAnalystEst()

Dim oHtml       As HTMLDocument
Dim oElement    As IHTMLElement

Set oHtml = New HTMLDocument

With CreateObject("WINHTTP.WinHTTPRequest.5.1")
    .Open "GET", "http://www.marketwatch.com/investing/stock/aapl/analystestimates", False
    .send
    oHtml.body.innerHTML = .responseText
End With

Dim wsTarget As Worksheet
Dim i As Integer
i = 1
Set wsTarget = ActiveWorkbook.Worksheets("Sheet1")

For Each oElement In oHtml.getElementsByClassName("snapshot")
  wsTarget.Range("A" & i) = Split(oElement.Children(0).innerText, "<TD>")
  i = i + 1
Next

End Sub

Here is the HTML I am trying to pull from. Can someone please give an example of how I could extract the average target price of 146.52?

<div class="analystEstimates">

<div class="block">
    <h2>Snapshot</h2>
</div>
<table class="snapshot">
    <tbody>
        <tr>
            <td class="first">Average Recommendation:</td>
            <td class="recommendation">
                Overweight
            </td>
            <td class="first column2">Average Target Price:</td>
            <td>146.52</td>
        </tr>
        <tr>
            <td class="first">Number of Ratings:</td>
            <td>
2
  • Why not just look at innerText and use a Regular Expression to get at the value you want? Commented Dec 5, 2015 at 2:12
  • 1
    If you can rely on the layout, and don't have go searching for "Average Target Price", then Split(oHtml.getElementsByClassName("snapshot").item(0).firstchild.firstchild.innerhtml,"TD")(7) would return: >146.52</ which you could then clean up. Commented Dec 5, 2015 at 2:34

3 Answers 3

1

I was able to solve my issue with the following:

Sub ImportAnalystEst()
Dim oHtml       As HTMLDocument
Dim oElement    As IHTMLElement

Set oHtml = New HTMLDocument


With CreateObject("WINHTTP.WinHTTPRequest.5.1")
    .Open "GET", "http://www.marketwatch.com/investing/stock/aapl/analystestimates", False
    .send
    oHtml.body.innerHTML = .responseText
End With

Dim wsTarget As Worksheet
Dim i As Integer
i = 1
Set wsTarget = ActiveWorkbook.Worksheets("Sheet1")


For Each oElement In oHtml.getElementsByClassName("snapshot")
  wsTarget.Range("A" & i) = Split(oHtml.getElementsByClassName("snapshot").Item(0).FirstChild.FirstChild.innerHTML, "TD")(7)
  wsTarget.Range("A" & i) = Replace(wsTarget.Range("A" & i), ">", "")
  wsTarget.Range("A" & i) = Replace(wsTarget.Range("A" & i), "</", "")
  i = i + 1
Next


End Sub
Sign up to request clarification or add additional context in comments.

3 Comments

Why do you have the For Each ... Next loop?
I am actually going to be looping through a series of iterations. That is the next step in my process. I am creating and troubleshooting that now. My final product will actually have a couple hundred stock symbols in column A and then put the analyst estimate in column E. So the GET function as well as the For Each function will have to be some sort of loop. You may have noticed the “aapl” in the above example. That is the stock symbol that will change based on column A. Do you have any suggestions for a corrected or more efficient structure?
I would check to see if you can obtain multiple quotes from marketwatch with a single call, for the parameters in which you are interested. I do that with Fidelity, but I am only looking for current quotes and time.
1

Far easier to use a CSS selector combination to target the value by it's position as the first row table cell in the second column of the table. The CSS selector is .snapshot .first.column2 + td which uses "." class selector, " " descendant combinator, and "+" adjacent sibling combinator.

Option Explicit
Public Sub ImportAnalystEst()
    Dim oHtml       As HTMLDocument
    Dim oElement    As IHTMLElement

    Set oHtml = New HTMLDocument

    With CreateObject("WINHTTP.WinHTTPRequest.5.1")
        .Open "GET", "http://www.marketwatch.com/investing/stock/aapl/analystestimates", False
        .send
        oHtml.body.innerHTML = .responseText
    End With
    Debug.Print oHtml.querySelector(".snapshot .first.column2 + td").innertext
End Sub

Comments

0

This will do what you want.

Sub Test() Dim IE As Object

Set IE = CreateObject("InternetExplorer.Application")
With IE
    .Visible = True
    .Navigate "http://www.marketwatch.com/investing/stock/aapl/analystestimates" ' should work for any URL
    Do Until .ReadyState = 4: DoEvents: Loop

        x = .document.body.innertext
        y = InStr(1, x, "Average Target Price:")
        Z = Mid(x, y, 6)

        Range("A1").Value = Trim(Z)

        .Quit
    End With
End Sub

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.