VBA 雅虎财经财务数据的 data-reactid
VBA data-reactid for Yahoo Finance's financial numbers
我在 google 上搜索了 data-reactid,它似乎在大多数情况下不适用于 VBA。
不过我觉得还是有可能得到答案的。
我想获得“经营活动现金流总额”中的数字
https://finance.yahoo.com/quote/BABA/cash-flow?p=BABA
Sub YFinance()
Dim XMLReq As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument
Dim i As Integer
Dim strUrl As String
XMLReq.Open "GET", "https://finance.yahoo.com/quote/BABA/cash-flow?p=BABA", False
XMLReq.send
If XMLReq.Status <> 200 Then
MsgBox "Error!"
Exit Sub
End If
HTMLDoc.body.innerHTML = XMLReq.responseText
Set XMLReq = Nothing
MsgBox HTMLDoc.getElementsById("Bdbw(0px)! H(36px)")(0).innerText
End Sub
getElementById
returns 单个节点,因此您不会像现在这样对其进行索引。没有方法 getElementsById
所以应该失败并出现错误。
您可以使用 class 并将特殊字符和索引转义到返回的集合中
MsgBox HTMLDoc.querySelectorAll(".Bdbw\(0px\)\!")(1).innerText
或将化合物 class 传递给 getElementsByClassName
:
MsgBox HTMLDoc.getElementsByClassName("Bdbw(0px)! H(36px)")(1).innerText
属性(不是 id)data-reactid
可以在页面和输出之间变化(就像在这种情况下一样 - 输出中的行的 id 是 113 . 在这种情况下,使用 table 和行索引
可能更安全
MsgBox HTMLDoc.getElementsByTagName("table")(2).getElementsByTagName("tr")(9).innerText
如果您希望该行逐列显示:
Dim td As Object, tds As Object
Set tds = HTMLDoc.getElementsByTagName("table")(2).getElementsByTagName("tr")(9).getElementsByTagName("td")
For Each td In tds
Debug.Print td.innerText
Next
或
Dim td As Object, tds As Object
Set tds = HTMLDoc.getElementsByClassName("Bdbw(0px)! H(36px)")(1).getElementsByTagName("td")
For Each td In tds
Debug.Print td.innerText
Next
正如我所说,data-reactid 可以灵活变化,但如果您想知道如何为此应用属性选择器,请参阅:
MsgBox HTMLDoc.querySelector("tr[data-reactid='113']").innerText
您可以尝试以下操作以确保安全。一旦 for loop
获得所需的节点,它将为您获取所需的内容并退出循环。
Sub FetchFinanceInfo()
Dim XMLReq As New XMLHTTP60, HTMLDoc As New HTMLDocument
Dim post As Object, I&
XMLReq.Open "GET", "https://finance.yahoo.com/quote/BABA/cash-flow?p=BABA", False
XMLReq.send
HTMLDoc.body.innerHTML = XMLReq.responseText
For Each post In HTMLDoc.getElementsByTagName("span")
If InStr(post.innerText, "From Operating Activities") > 0 Then
With post.ParentNode.ParentNode.getElementsByTagName("td")
For I = 1 To .Length - 1
Debug.Print .Item(I).innerText
Next I
End With
Exit For
End If
Next post
End Sub
我在 google 上搜索了 data-reactid,它似乎在大多数情况下不适用于 VBA。
不过我觉得还是有可能得到答案的。 我想获得“经营活动现金流总额”中的数字
https://finance.yahoo.com/quote/BABA/cash-flow?p=BABA
Sub YFinance()
Dim XMLReq As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument
Dim i As Integer
Dim strUrl As String
XMLReq.Open "GET", "https://finance.yahoo.com/quote/BABA/cash-flow?p=BABA", False
XMLReq.send
If XMLReq.Status <> 200 Then
MsgBox "Error!"
Exit Sub
End If
HTMLDoc.body.innerHTML = XMLReq.responseText
Set XMLReq = Nothing
MsgBox HTMLDoc.getElementsById("Bdbw(0px)! H(36px)")(0).innerText
End Sub
getElementById
returns 单个节点,因此您不会像现在这样对其进行索引。没有方法 getElementsById
所以应该失败并出现错误。
您可以使用 class 并将特殊字符和索引转义到返回的集合中
MsgBox HTMLDoc.querySelectorAll(".Bdbw\(0px\)\!")(1).innerText
或将化合物 class 传递给 getElementsByClassName
:
MsgBox HTMLDoc.getElementsByClassName("Bdbw(0px)! H(36px)")(1).innerText
属性(不是 id)data-reactid
可以在页面和输出之间变化(就像在这种情况下一样 - 输出中的行的 id 是 113 . 在这种情况下,使用 table 和行索引
MsgBox HTMLDoc.getElementsByTagName("table")(2).getElementsByTagName("tr")(9).innerText
如果您希望该行逐列显示:
Dim td As Object, tds As Object
Set tds = HTMLDoc.getElementsByTagName("table")(2).getElementsByTagName("tr")(9).getElementsByTagName("td")
For Each td In tds
Debug.Print td.innerText
Next
或
Dim td As Object, tds As Object
Set tds = HTMLDoc.getElementsByClassName("Bdbw(0px)! H(36px)")(1).getElementsByTagName("td")
For Each td In tds
Debug.Print td.innerText
Next
正如我所说,data-reactid 可以灵活变化,但如果您想知道如何为此应用属性选择器,请参阅:
MsgBox HTMLDoc.querySelector("tr[data-reactid='113']").innerText
您可以尝试以下操作以确保安全。一旦 for loop
获得所需的节点,它将为您获取所需的内容并退出循环。
Sub FetchFinanceInfo()
Dim XMLReq As New XMLHTTP60, HTMLDoc As New HTMLDocument
Dim post As Object, I&
XMLReq.Open "GET", "https://finance.yahoo.com/quote/BABA/cash-flow?p=BABA", False
XMLReq.send
HTMLDoc.body.innerHTML = XMLReq.responseText
For Each post In HTMLDoc.getElementsByTagName("span")
If InStr(post.innerText, "From Operating Activities") > 0 Then
With post.ParentNode.ParentNode.getElementsByTagName("td")
For I = 1 To .Length - 1
Debug.Print .Item(I).innerText
Next I
End With
Exit For
End If
Next post
End Sub