VBA doesn't read XMLHTTP request's response according to its tree structure

末鹿安然 提交于 2020-07-07 04:05:50

问题


I have checked that both browser-generated page and VBA XMLHTTP request's string response have the same tree structure, with a tag being a child of aside.

Unfortunately when I want to return bookie name, which is title attribute of a, I get an error accessing 1st child of aside. It comes out that I need to use code assuming that a tag is a sibling of aside to get it working:

Required reference: Microsoft HTML Library

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

Does this behavior have something to do with the fact that aside is HTML5 element and VBA thinks that it is a semi-closing tag?


回答1:


So this took awful lot of time to figure out. The issue is that you can't do it this way. When you launch a new HTMLDocument the documentMode of it is by default set to 5

So when we load a write any HTML inside it, it has no idea of these HTML5 tags and it just does its own correction. This is as good as you running HTML5 site in a IE6 browser or something. Unfortunately there is no way I could find out which would allow us to create/parse document with a higher documentMode

Update

Thanks to @FlorentB for pointing out that emulation mode works on the MSHTML library as well. I was already aware of the same from below

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

But I assumed it won't work for the MSHTML library. I have now tested it by running below command

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

And then the existing code and it works.

Alternat approach

If setting the registry key needs to be avoided for any reason then one can use the IE COM Browser directly.

You can do this by adding a reference to Microsoft Internet Controls and then execute the below code

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

And now you can see that a is a child of aside



来源:https://stackoverflow.com/questions/49501406/vba-doesnt-read-xmlhttp-requests-response-according-to-its-tree-structure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!