VBA根据其树结构不读取XMLHTTP请求的响应

时间:2018-03-26 22:07:43

标签: vba xmlhttprequest

我已经检查过,浏览器生成的页面和VBA XMLHTTP请求的字符串响应都具有相同的树结构, a 标记是 的子项。

不幸的是,当我想要返回bookie name,这是 a 的title属性时,我在访问的第一个孩子时遇到错误。我需要使用代码,假设 标记是一边的兄弟,以使其正常工作:

enter image description here

必需参考:Microsoft HTML库

Sub SendRequest()

Dim XMLHTTP As Object: Set XMLHTTP = CreateObject("MSXML2.XMLHTTP.6.0")
Dim htmlEle1 As IHTMLElement
Dim htmlDoc As New HTMLDocument   
Dim urlName As String

urlName = "https://www.oddschecker.com/golf/the-masters/2018-us-masters/winner"

With XMLHTTP

    .Open "GET", urlName, False
    .send
    htmlDoc.body.innerHTML = .responseText

    For Each htmlEle1 In htmlDoc.getElementsByClassName("eventTableHeader")(0).Children
        If InStr(htmlEle1.className, "bookie-area") <> 0 Then
           Debug.Print htmlEle1.Children(1).getAttribute("title")
        End If
    Next htmlEle1

End With

End Sub

这种行为是否与搁置是HTML5元素并且VBA认为它是半结束标记这一事实有关?

1 个答案:

答案 0 :(得分:2)

所以这花了很多时间才弄明白。问题是你不能这样做。当您发布新的HTMLDocument时,其documentMode默认设置为5

因此,当我们在其中加载任何HTML时,它不知道这些HTML5标记,它只是进行自己的修正。这与在IE6浏览器中运行HTML5站点一样好。 不幸的是我无法找到哪个允许我们用更高的documentMode创建/解析文档

<强>更新

感谢@FlorentB指出仿真模式也适用于MSHTML库。我已经从下面知道了同样的事情

Embedding Youtube Videos in webbrowser. Object doesn't support property or method

但我认为它不适用于MSHTML库。我现在通过运行以下命令

测试它
REG ADD "HKCU\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION" /v excel.exe /t REG_DWORD /d 11001 /f

然后是现有的代码并且它可以工作。

Alternat方法

如果出于任何原因需要避免设置注册表项,则可以直接使用IE COM浏览器。

您可以通过添加对Microsoft Internet Controls的引用然后执行以下代码

来执行此操作
Sub dothis()
Dim XMLHTTP As Object: Set XMLHTTP = CreateObject("MSXML2.XMLHTTP.6.0")
Dim htmlEle1 As IHTMLElement
Dim htmlDoc As HTMLDocument
'Set htmlIDoc = htmlDoc

Dim urlName As String

urlName = "https://www.oddschecker.com/golf/the-masters/2018-us-masters/winner"

Dim ie As InternetExplorerMedium

Set ie = New InternetExplorerMedium

ie.Visible = False
ie.navigate2 urlName

While ie.readyState <> READYSTATE_COMPLETE

    DoEvents
Wend

Set htmlDoc = ie.document

Debug.Print (htmlDoc.documentMode)
For Each htmlEle1 In htmlDoc.getElementsByClassName("eventTableHeader")(0).Children
    If InStr(htmlEle1.className, "bookie-area") <> 0 Then
       Debug.Print htmlEle1.Children(0).children(0).getAttribute("title")
    End If
Next htmlEle1

End Sub

现在您可以看到aaside

的孩子

HTML5 Parsing