3

I am trying to convert some of my working VBA code to VBScript, but keep getting errors in VBScript when trying to use the getElementsByClassName method. Here's the full code:

option explicit

Dim XMLPage, html

Set XMLPage = WScript.CreateObject("MSXML2.XMLHTTP")
Set html= CreateObject("HTMLFile")

XMLPage.Open "GET", "https://www.hltv.org/stats/matches/mapstatsid/48745/immortals-vs-dignitas", False
Wscript.Sleep 50
XMLPage.send
Wscript.Sleep 50
If XMLPage.Status <> 200 Then MsgBox XMLPage.statusText

html.Open
html.write XMLPage.responseText
html.Close

'msgbox html.getElementsByTagName("tbody")(0).innertext'WORKS
msgbox html.getElementsByClassName("match-info-box-con")(0).innertext'DOESNT WORK

The last line of code is where the following error occurs: enter image description here

If I comment that out and run it to search for a tag name instead (code on the line above) - it works fine no problem.

I suspect it has something to do with how the variable html is declared, as from what I understand. getElementsByClassName comes from IHTMLElement6 - but I am unsure on how to get this to work in VBScript.

8
  • comes from IHTMLElement6 - also from IHTMLDocument7. Should work on Vista+. You can also try it on html.body. Commented Jun 30, 2017 at 20:35
  • Thanks, could you please help me by advising how I would apply this to the above code? As this is in VBScript, I have to make all declarations within the code as I can't select references same as what I could in VBA. Commented Jun 30, 2017 at 20:55
  • html.body.getElementsByClassName? Commented Jun 30, 2017 at 21:24
  • Thanks, I tried this and got the same error - only in this case it said: doesn't support 'body.getElementsByClassName'. If you have any more ideas on how this could be solved - would be much appreciated. Thanks. Commented Jun 30, 2017 at 21:34
  • 2
    MSHTML behaves differently depending on how it was instantiated - it exposes different interfaces depending on whether or not its early or late bound (its heavily reliant on IDispatch). You are late binding and no interface exposing getElementsByClassName is available. You can loop over document.all() and look at each item.className. Commented Jul 1, 2017 at 12:20

3 Answers 3

3

MSHTML behaves differently depending on how it was instantiated - it exposes different interfaces depending on whether or not its early or late bound (its heavily reliant on IDispatch).

You are late binding and no interface exposing getElementsByClassName is available.

You can loop over document.all() and look at each item.className.

Sign up to request clarification or add additional context in comments.

1 Comment

Isn't there a way to specify the desired version of MSXML when late binding?
0

I used similar code to retrieve data from a POST request. getElementsByClassName worked only if preceded with another command, like "msgbox 1" or anything to halt the script for a fraction of a second. Then I tried Wscript.Sleep 200, decreasing it to the smallest possible number, and it still worked.

Wscript.Sleep 1 ' This line got it working.
msgbox html.getElementsByClassName("match-info-box-con")(0).innertext'

2 Comments

It would appear that your problem was that you did not let the document time to load which happens in the background. This has nothing to do with the OP's problem.
Actually, without that 1 milisecond, the error was the same. I have no idea why 1 milisecond is enough, but is proof that getElementsByClassName is indeed supported. No need for another way initialize the html object.
0

I took some time to elaborate a working example. Thanks to GSerg for pointing out the load delay. That is accurate. Had to tweak the code a little to get it working though. Based on the previous comments, maybe the behaviour of MSHTML depends on the code being parsed. Hence the aditional meta tag below.

Set objHTTP = CreateObject("MSXML2.XMLHTTP")
Dim htmldoc: Set htmldoc = CreateObject("htmlfile") 
'    
URL = "https://stackoverflow.com/questions/44853941/vbscript-getelementsbyclassname-not-supported"
'   sEnv = ""
'    
objHTTP.Open "GET", URL, False
'    objHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
objHTTP.send ' (sEnv)
ttext = objHTTP.responsetext

ttext = "<meta http-equiv=""X-UA-Compatible"" content=""IE=EDGE,chrome=1"" />" & vbnewline & ttext 

htmldoc.write ttext
htmldoc.close
htmldoc.designMode = "on"   ' Refer to https://developpaper.com/method-of-parsing-html-documents-by-vbs-htmlfile/

WScript.ConnectObject htmldoc, "htmldoc_"

Sub htmldoc_onreadystatechange()
  If htmldoc.readyState = "interactive" Then
      ttext = htmldoc.getElementsByClassName("fs-headline1").Item(0).innerText
      msgbox ttext
      Wscript.quit
  End If
End Sub

'-----------------
Wscript.Sleep 10000  ' Random timeout
msgbox "Timeout!"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.