我正在寻找一种可能性,可以根据 VBA 从雅虎财经中抓取财务数据。 我的问题是我之前没有使用过 VBA,我在这里找到的所有解决方案(如果我错了,请纠正我)都没有通过我对任务的要求,如下:
抓取应该可以转移到不同的库存(例如 GOOG、MSFT 等),这意味着表格的长度会有所不同。在这里,我当前的问题是:results(r + 1, c + 1) = row.Item(c).innerText
就像我在几个网页上收到错误“索引超出有效范围”一样:https://de.finance.yahoo.com/quote/GOOG/financials?p=GOOG,尽管通过 .length
的动态定义实际上应该是可用,不是吗?
应该收集所有(扩展的)财务数据。 (这里的当前问题是,下面显示的代码只是抓取了顶部条目并遗漏了详细信息(例如在 https://finance.yahoo.com/quote/GOOG/financials?p=GOOG 上:我还需要营业收入,而不仅仅是总收入)
我确信这些“问题”是基本的,但是经过 2 天的尝试和研究 VBA 和 HTML,我仍然没有可用的代码。
在此先谢谢你!!
这里是迄今为止效果最好的代码:
Option Explicit
Public Sub WriteOutFinancialInfo()
'Allgemeine Variablendefinition
Dim http As Object, s As String
Set http = CreateObject("MSXML2.XMLHTTP")
'Website aufrufen
With http
.Open "GET", "https://de.finance.yahoo.com/quote/GOOG/financials?p=GOOG", False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.send
s = .responseText
End With
'Variablen mit Werten aus Website füllen
Dim html As MSHTML.HTMLDocument, html2 As MSHTML.HTMLDocument, re As Object, matches As Object
Set html = New MSHTML.HTMLDocument: Set html2 = New MSHTML.HTMLDocument
Set re = CreateObject("VBScript.RegExp")
html.body.innerHTML = s
'Tabelle aufsetzen
Dim headers(), rows As Object
headers = Array("Aufschlüsselung", "TTM") 'hier Werte (Überschriften) der ersten beiden Zellen definieren'
Set rows = html.querySelectorAll(".fi-row")
With re
.Global = True
.MultiLine = True
.Pattern = "\d{1,2}/\d{1,2}/\d{4}"
Set matches = .Execute(s)
End With
Dim results(), match As Object, r As Long, c As Long, startHeaderCount As Long
startHeaderCount = UBound(headers)
ReDim Preserve headers(0 To matches.Count + startHeaderCount)
c = 1
For Each match In matches
headers(startHeaderCount + c) = match
c = c + 1
Next
'Unterschied zwischen innerHTML und outerHTML ist, dass bei outerHTML auch der Code um den Inhalt berücksichtigt wird.
Dim row As Object
ReDim results(1 To rows.Length, 1 To UBound(headers) + 1)
For r = 0 To rows.Length - 1
html2.body.innerHTML = rows.Item(r).outerHTML
Set row = html2.querySelectorAll("[title],[data-test=fin-col]")
For c = 0 To row.Length - 1
results(r + 1, c + 1) = row.Item(c).innerText
Next c
Next
'Definition des Ausgabe-Arbeitsblatts und Ausgabe der Ergebnisse
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Tabelle1")
With ws
.Cells(3, 3).Resize(1, UBound(headers) + 1) = headers
.Cells(4, 3).Resize(UBound(results, 1), UBound(results, 2)) = results
End With
End Sub