VBA 没有 class 名称或 ID 的网络抓取内容
VBA web scraping contents without class name or ID
我想从香港交易所获取股息期货价格。
我想通过 VBA 刮取 "Dec-19 Contract" 的 Prev.Day 结算价。
但是,它没有任何 class 名称或 ID,所以我不知道如何访问这些信息。
<tr>
<td>Dec-19</td>
<td>-</td>
<td>-</td>
<td>413.78</td>
<td>
-
<br>
-
</td>
<td>-</td>
<td>
-
<br>
-
</td>
<td>-<td>
<td>17,330</td>
</tr>
如何通过 VBA 抓取这个?
使用 getElementsByTagName。确定您的身份,然后逐行浏览每一行和每个 td。像那样的东西。
Dim objTR As IHTMLElement
Dim objTD As IHTMLElement
Dim objTable As IHTMLElement
For Each objTR In objTable.getElementsByTagName("tr")
For Each objTD In objTR
'do something with objtd.innerText
Next objTD
Next objTR
或者如果您更喜欢后期绑定,您可以将变量声明为对象。
查找没有附加显着标志的特定项目的自动化真的很糟糕。但是,我编写的这个脚本没有对元素进行硬编码索引。试一试并获得您想要的值:
Sub Hkex_Data()
Dim IE As New InternetExplorer, html As HTMLDocument
Dim posts As Object
With IE
.Visible = False
.navigate "http://www.hkex.com.hk/Market-Data/Futures-and-Options-Prices/Equity-Index/HSCEI-Dividend-Futures?sc_lang=en#&product=DHH"
Do Until .readyState = READYSTATE_COMPLETE: Loop
Set html = .document
End With
Application.Wait (Now + TimeValue("0:00:05"))
For Each posts In html.getElementsByClassName("hsirowcon")
Row = Row + 1: Cells(Row, 1) = posts.NextSibling.NextSibling.FirstChild.innerText
Cells(Row, 2) = posts.NextSibling.NextSibling.LastChild.innerText
Next posts
IE.Quit
End Sub
结果:
19-Dec 17,330
要添加到库中的引用:
Microsoft internet controls
Microsoft Html Object Library
您也可以简单地使用 CSS 选择器而不使用循环:
html.querySelectorAll("td:nth-child(4)")(1).innerText
这个方法很脆弱。如果页面上的样式发生变化,这可能会中断。
CSS 选择器:
如果您观察页面的相关部分(显示第一个合同年,上下文 headers 并且合同年之间的图表已删除):
2019 合同年的关联 HTML 是:
Prev.Day Settlement Price
是其中的第 4 个 td
,即 CSS 选择器 td:nth-child(4)
。
此模式在所有合同年度重复,因此您可以 return 一个包含所有匹配项的节点列表(即每个 td:nth-child(4)
使用 .querySelectorAll
方法)。
2019 年在索引位置 1;这是基于 0 的索引节点列表中的第二个元素,因此您可以使用 .querySelectorAll("td:nth-child(4)")(1)
.
进行访问
CSS查询结果-前几个结果:
我想从香港交易所获取股息期货价格。
我想通过 VBA 刮取 "Dec-19 Contract" 的 Prev.Day 结算价。 但是,它没有任何 class 名称或 ID,所以我不知道如何访问这些信息。
<tr>
<td>Dec-19</td>
<td>-</td>
<td>-</td>
<td>413.78</td>
<td>
-
<br>
-
</td>
<td>-</td>
<td>
-
<br>
-
</td>
<td>-<td>
<td>17,330</td>
</tr>
如何通过 VBA 抓取这个?
使用 getElementsByTagName。确定您的身份,然后逐行浏览每一行和每个 td。像那样的东西。
Dim objTR As IHTMLElement
Dim objTD As IHTMLElement
Dim objTable As IHTMLElement
For Each objTR In objTable.getElementsByTagName("tr")
For Each objTD In objTR
'do something with objtd.innerText
Next objTD
Next objTR
或者如果您更喜欢后期绑定,您可以将变量声明为对象。
查找没有附加显着标志的特定项目的自动化真的很糟糕。但是,我编写的这个脚本没有对元素进行硬编码索引。试一试并获得您想要的值:
Sub Hkex_Data()
Dim IE As New InternetExplorer, html As HTMLDocument
Dim posts As Object
With IE
.Visible = False
.navigate "http://www.hkex.com.hk/Market-Data/Futures-and-Options-Prices/Equity-Index/HSCEI-Dividend-Futures?sc_lang=en#&product=DHH"
Do Until .readyState = READYSTATE_COMPLETE: Loop
Set html = .document
End With
Application.Wait (Now + TimeValue("0:00:05"))
For Each posts In html.getElementsByClassName("hsirowcon")
Row = Row + 1: Cells(Row, 1) = posts.NextSibling.NextSibling.FirstChild.innerText
Cells(Row, 2) = posts.NextSibling.NextSibling.LastChild.innerText
Next posts
IE.Quit
End Sub
结果:
19-Dec 17,330
要添加到库中的引用:
Microsoft internet controls
Microsoft Html Object Library
您也可以简单地使用 CSS 选择器而不使用循环:
html.querySelectorAll("td:nth-child(4)")(1).innerText
这个方法很脆弱。如果页面上的样式发生变化,这可能会中断。
CSS 选择器:
如果您观察页面的相关部分(显示第一个合同年,上下文 headers 并且合同年之间的图表已删除):
2019 合同年的关联 HTML 是:
Prev.Day Settlement Price
是其中的第 4 个 td
,即 CSS 选择器 td:nth-child(4)
。
此模式在所有合同年度重复,因此您可以 return 一个包含所有匹配项的节点列表(即每个 td:nth-child(4)
使用 .querySelectorAll
方法)。
2019 年在索引位置 1;这是基于 0 的索引节点列表中的第二个元素,因此您可以使用 .querySelectorAll("td:nth-child(4)")(1)
.
CSS查询结果-前几个结果: