【问题标题】:VBA doesn't read XMLHTTP request's response according to its tree structureVBA 不会根据其树结构读取 XMLHTTP 请求的响应
【发布时间】:2018-09-05 04:26:18
【问题描述】:

我检查了浏览器生成的页面和 VBA XMLHTTP 请求的字符串响应具有相同的树结构,其中 a 标记是 aside 的子标记。

不幸的是,当我想返回 a 的标题属性 bookie 名称时,访问 aside 的第一个孩子时出错。结果表明,我需要使用代码假设 a 标记是 aside 的兄弟才能使其正常工作:

必填参考: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

这种行为是否与 aside 是 HTML5 元素而 VBA 认为它是一个半关闭标签这一事实有关?

【问题讨论】:

  • 代替htmlDoc.body.innerHTML = .responseText 尝试htmlDoc.clear() 然后htmlDoc.write(.responseText)
  • 无法使用 HtmlDoc.write -“编译错误:函数或接口标记为受限,或函数使用 Visual Basic 不支持的自动化类型”
  • 你能用IHTMLDocument2接口把文档转换成另一个对象吗?

标签: vba xmlhttprequest


【解决方案1】:

所以这花了很多时间来弄清楚。问题是你不能这样做。当您启动一个新的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

然后现有的代码就可以工作了。

替代方法

如果出于某种原因需要避免设置注册表项,则可以直接使用 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 的子代

【讨论】:

  • 执行REG ADD "HKCU\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION" /v excel.exe /t REG_DWORD /d 11001 /f并重启​​excel将New HTMLDocument的文档模式设置为IE11
  • 感谢@FlorentB.,我知道 IE 浏览器的仿真设置,从没想过它也适用于 MSHTML 库。感谢您指出了这一点。我已经测试过了,效果很好
  • 尝试在 IE 设置中将网站添加到受信任的网站,看看是否有帮助,您的系统上的 IE 版本是什么?
  • 那么这两种方法都应该有效,我已经在 Windows 7 + IE 11 上测试过
猜你喜欢
  • 2021-05-27
  • 1970-01-01
  • 1970-01-01
  • 2020-10-15
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多