netspeedz
New Member
- Joined
- Aug 11, 2011
- Messages
- 21
I've been struggling to get the below VBA subroutine to fully extract data from a Kitco website page. I can get everything to populate a table on a spreadsheet except the last 3 columns of the two rows of data I'm extracting.
I'm thinking this is a case of 'not seeing the tree because of the forest' and need fresh eyes on the code. Would appreciate any help/insight on what I need to adjust in the code to get the last three columns of data (Change(%), Low and High). VBA code below:
I'm thinking this is a case of 'not seeing the tree because of the forest' and need fresh eyes on the code. Would appreciate any help/insight on what I need to adjust in the code to get the last three columns of data (Change(%), Low and High). VBA code below:
VBA Code:
Sub ScrapeGoldAndSilverData()
Dim request As Object
Dim response As String
Dim html As Object
Dim metals As Object
Dim metal As Object
Dim targetSheet As Worksheet
Dim rowNum As Integer
Dim dataPoints As Object
Dim headerTitles As Variant
Dim metalNames As Variant
' Create XMLHTTP request
Set request = CreateObject("MSXML2.XMLHTTP")
' URL of the webpage to scrape
request.Open "GET", "https://www.kitco.com/price/precious-metals", False
request.send
' Get response text
response = request.responseText
' Create a new HTML document
Set html = CreateObject("HTMLFile")
html.body.innerHTML = response
' Set the target sheet
Set targetSheet = ThisWorkbook.Sheets("External Data")
' Define column headers
headerTitles = Array("Metal", "Date", "Time(EST)", "Bid", "Ask", "Change", "Change(%)", "Low", "High")
' Write column headers
For colNum = LBound(headerTitles) To UBound(headerTitles)
targetSheet.Cells(20, colNum + 1).Value = headerTitles(colNum)
Next colNum
' Start writing data from row 21, column 1 (A)
rowNum = 21
' Find all the metals data under New York Spot Price section
Set metals = html.getElementsByClassName("BidAskGrid_listify__1liIU")(0).getElementsByTagName("li")
' Array of metals to filter
metalNames = Array("Gold", "Silver")
' Loop through each metal's data
For Each metal In metals
On Error Resume Next ' Continue on error
' Write other data points
Set dataPoints = metal.getElementsByClassName("BidAskGrid_gridifier__l1T1o")(0).Children
' Extract the metal name
Dim currentMetal As String
currentMetal = dataPoints(0).getElementsByTagName("a")(0).innerText
' Check if it's Gold or Silver
If UBound(Filter(metalNames, currentMetal)) > -1 Then
' Write metal name
targetSheet.Cells(rowNum, 1).Value = currentMetal
' Date, Time(EST), Bid, Ask
targetSheet.Cells(rowNum, 2).Value = dataPoints(1).innerText
targetSheet.Cells(rowNum, 3).Value = dataPoints(2).innerText
targetSheet.Cells(rowNum, 4).Value = dataPoints(3).innerText
targetSheet.Cells(rowNum, 5).Value = dataPoints(4).innerText
' Extracting Change, Change(%), Low, and High values
Dim changeText As String
changeText = Replace(dataPoints(5).innerText, Chr(34), "") ' Remove double quotes
Dim changeParts() As String
changeParts = Split(changeText, vbCrLf)
If UBound(changeParts) >= 1 Then
targetSheet.Cells(rowNum, 6).Value = changeParts(1) ' Change(%)
targetSheet.Cells(rowNum, 7).Value = Replace(changeParts(0), vbCrLf, "|") ' Change
End If
Dim lowHighText As String
lowHighText = dataPoints(6).innerText
Dim lowHighParts() As String
lowHighParts = Split(lowHighText, vbCrLf)
If UBound(lowHighParts) >= 1 Then
targetSheet.Cells(rowNum, 8).Value = lowHighParts(0) ' Low
targetSheet.Cells(rowNum, 9).Value = lowHighParts(1) ' High
End If
' Move to the next row
rowNum = rowNum + 1
End If
On Error GoTo 0 ' Re-enable error handling
Next metal
' Release memory
Set request = Nothing
Set html = Nothing
Set targetSheet = Nothing
End Sub