VBA 没有 class 名称或 ID 的网络抓取内容

VBA web scraping contents without class name or ID

我想从香港交易所获取股息期货价格。

这是本网站的 URL: http://www.hkex.com.hk/Market-Data/Futures-and-Options-Prices/Equity-Index/HSCEI-Dividend-Futures?sc_lang=en#&product=DHH

我想通过 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查询结果-前几个结果: