vba GetElementsbyClassname:打开 IE 与 MSXML2 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23476502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 18:10:07  来源:igfitidea点击:

GetElementsbyClassname: Open IE vs. MSXML2 Methods

vbainternet-explorerexcel-vbagetelementsbyclassnameexcel

提问by ron

The following macro works just fine. It opens an instance of IE and uses the "getelementsbyclassname" method to return the expected value for "my_rate". However when I run the second macro which uses the "MSXML2" method, the macro fails on the noted line and a "Run-time error 438: Object doesn't support this property or method" error occurs. Why does the "Open IE" method work, but the "MSXML2" method fail with my code? I am running with IE 11. I also have a reference set to the Microsoft HTML Object Library for the second macro, but it doesn't seem to make a difference. Thanks in advance for explaining this to me.

下面的宏工作得很好。它打开一个 IE 实例并使用“getelementsbyclassname”方法返回“my_rate”的预期值。但是,当我运行使用“MSXML2”方法的第二个宏时,该宏在注释行上失败,并出现“运行时错误 438:对象不支持此属性或方法”错误。为什么“Open IE”方法有效,但“MSXML2”方法在我的代码中失败?我正在使用 IE 11。我也为第二个宏设置了对 Microsoft HTML 对象库的引用,但它似乎没有什么区别。预先感谢您向我解释这一点。

Sub BankRate_Rate_Retrieval()
    my_url = "http://www.bankrate.com/funnel/mortgages/mortgage-results.aspx?market=321&loan=150000&perc=20&prods=2&points=0"   
    Set ie = CreateObject("InternetExplorer.Application")

    With ie
        .Visible = True
        .Navigate my_url
        .Top = 50
        .Left = 530
        .Height = 400
        .Width = 400
    End With

    Do Until Not ie.Busy And ie.readyState = 4
        DoEvents
    Loop

    my_rate = ie.Document.getelementsbyclassname("br-col-2 br-apr")(1).getElementsByTagName("div")(0).innertext
End Sub


Sub BankRate_Rate_Retrieval()
    my_url = "http://www.bankrate.com/funnel/mortgages/mortgage-results.aspx?market=321&loan=150000&perc=20&prods=2&points=0"
    Set html_doc = CreateObject("htmlfile")
    Set xml_obj = CreateObject("MSXML2.XMLHTTP")

    xml_obj.Open "GET", my_url, False
    xml_obj.send
    html_doc.body.innerhtml = xml_obj.responseText
    Set xml_obj = Nothing

    my_rate = html_doc.body.getelementsbyclassname("br-col-2 br-apr")(1).getElementsByTagName("div")(0).innertext

' Run-time error 438: Object doesn't support this property or method occurs on above line

' 运行时错误 438:对象不支持此属性或方法发生在上面的行

End Sub

结束子

Edit: Library Screenshot for D. Zemens

编辑:D. Zemens 的库截图

enter image description here

在此处输入图片说明

回答by David Zemens

The error message is pretty straightforward:

错误消息非常简单:

GetElementsByClassNameis not a method available in the Microsoft XML, v6.0 library.

GetElementsByClassName不是 Microsoft XML v6.0 库中可用的方法。

You can review the available methods, here:

您可以在此处查看可用的方法:

http://msdn.microsoft.com/en-us/library/aa926433.aspx

http://msdn.microsoft.com/en-us/library/aa926433.aspx

And while I can't find a similar documentation link, if you enable referenc to the MSHTML library, you can review there to confirm likewise, there is not GetElementsByClassNamemethod. This is a method that is available to IE automation but not to HTML or DOMDocument.

虽然我找不到类似的文档链接,但如果您启用对 MSHTML 库的引用,您可以查看那里以同样确认,没有GetElementsByClassName方法。这是一种可用于 IE 自动化但不适用于 HTML 或 DOMDocument 的方法。

enter image description here

在此处输入图片说明

UPDATED

更新

While this may not resolve your problem, I put it here in case it helps others with IE8. It seems to be working for this purpose, but may need to be refined.

虽然这可能无法解决您的问题,但我将其放在这里,以防它可以帮助其他人使用 IE8。它似乎为此目的而工作,但可能需要改进。

Option Explicit

Sub BankRate_Rate_Retrieval()
Dim my_url As String
Dim html_doc As Object 'HTMLDocument
Dim xml_obj As Object 'MSXML2.DOMDocument
Dim my_rate As String

my_url = "http://www.bankrate.com/funnel/mortgages/mortgage-results.aspx?market=321&loan=150000&perc=20&prods=2&points=0"

Set html_doc = CreateObject("htmlfile")
Set xml_obj = CreateObject("MSXML2.XMLHTTP")

xml_obj.Open "GET", my_url, False
xml_obj.send
html_doc.body.innerhtml = xml_obj.responseText

'attempt to replicate the GetElementsByClassName for IE8

my_rate = IE8_GetElementsByClassName(html_doc.body, "br-col-2 br-apr", 1).GetElementsByTagName("div")(0).InnerText

MsgBox my_rate


Set xml_obj = Nothing
Set html_doc = Nothing


End Sub

Function IE8_GetElementsByClassName(html As Object, className As String, Optional Position As Integer)
'Function to return an array of matching classname elements
' or if specified will return a single HTMLElement by Position index

Dim eleDict As Object
Dim ele as Variant
Set eleDict = CreateObject("Scripting.Dictionary")
For x = 0 To html.all.Length - 1
    Set ele = html.all(x)
    If ele.className = className Then
        'Debug.Print i & vbTab & x & vbTab & ele.InnerText
        Set eleDict(i) = ele
        i = i + 1
    End If
Next

If Position = Empty Then
    IE8_GetElementsByClassName = eleDict.Items
Else
    Set IE8_GetElementsByClassName = eleDict(Position)
End If
Set eleDict = Nothing
End Function