【问题标题】:Submit form and fetch data from website VBA提交表单并从网站 VBA 获取数据
【发布时间】:2015-01-24 14:02:19
【问题描述】:

我正在尝试使用 Excel 中的 VBA 从此 site 获取数据。我尝试做的和有效的方法是使用这样的 InternetExplorer 对象:

Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = False
IE.Navigate "http://zertifikate.finanztreff.de"
IE.document.getElementById("USFsecuritySearchDropDown").Value = "DE000BP5TBQ2"
IE.document.getElementById("USFsecuritySearchDropDownForm").submit

Do While IE.Busy Or IE.readyState <> 4  'wait until page is loaded
    Application.Wait DateAdd("s", 1, Now)
Loop
MsgBox IE.document.getElementById("BP5TBQ~30~5").innerHTML

但是,这工作非常缓慢,并且并不总是得到正确的结果。我怀疑有时它没有等到网页加载完毕。我试图寻找答案,我找到了this answer on stackoverflow。现在我想弄清楚如何使用 MSXML2 和 MSHTML 重写我的宏。到目前为止,我能够做到这一点:

Dim IE As MSXML2.XMLHTTP60
Set IE = New MSXML2.XMLHTTP60

IE.Open "GET", "http://zertifikate.finanztreff.de", False
IE.send
While IE.ReadyState <> 4
    DoEvents
Wend

Dim HTMLDoc As MSHTML.HTMLDocument
Dim htmlBody As MSHTML.htmlBody

Set HTMLDoc = New MSHTML.HTMLDocument
Set htmlBody = HTMLDoc.body
htmlBody.innerHTML = IE.responseText
HTMLDoc.getElementById("USFsecuritySearchDropDown").Value = "DE000BP5TBQ2"

请问,为什么 HTMLDoc 有方法 getElementById 而 htmlBody 没有?我如何提交表格“USFsecuritySearchDropDownForm”。我试过这个:

 HTMLDoc.getElementById("USFsecuritySearchDropDownForm").submit

,但它总是在我的默认浏览器中打开新窗口,我想隐藏它。 在我看来,我缺少 XMLHTTP60 和 MSHTML.HTMLDocument 之间的区别。 如果你能帮助我,或者至少告诉我在哪里可以找到这些信息,我将非常感激......

【问题讨论】:

    标签: excel vba msxml mshtml


    【解决方案1】:

    XMLHTTP 向网络服务器发送一个 http 请求并接收响应。 MSHTML 接收一个字符串并呈现 HTML。当您一起使用它们时,XMLHTTP 获取网络服务器响应,MSHTML 将该响应放入您可以使用的形式中。

    我认为您不需要提交任何内容。如果您访问该网站并输入代码,您将进入类似的页面

    http://zertifikate.finanztreff.de/dvt_einzelkurs_uebersicht.htn?seite=zertifikate&i=22558284&suchbegriff=DE000BP5TBQ2&exitPoint=

    里面有代码。您可以直接“获取”该 URL,并从返回的 html 中获取所需的任何信息。这个例子得到了我假设的股票价格。

    Sub GetPrice()
    
        Dim xHttp As MSXML2.XMLHTTP
        Dim hDoc As MSHTML.HTMLDocument
        Dim hDiv As HTMLDivElement
        Dim hTbl As HTMLTable
    
        Const sTICKER As String = "DE000BP5TBQ2"
    
        Set xHttp = New MSXML2.XMLHTTP
    
        xHttp.Open "GET", "http://zertifikate.finanztreff.de/dvt_einzelkurs_uebersicht.htn?seite=zertifikate&i=22558284&suchbegriff=" & sTICKER & "&exitPoint="
        xHttp.send
    
        Do Until xHttp.readyState = 4
            DoEvents
        Loop
    
        If xHttp.Status = 200 Then
            Set hDoc = New MSHTML.HTMLDocument
            hDoc.body.innerHTML = xHttp.responseText
    
            'Get the third TD in the first TABLE in the first DIV whose class is 'tape'
            Set hDiv = hDoc.getElementsByClassName("tape").Item(0)
            Set hTbl = hDiv.getElementsByTagName("table").Item(0)
            Debug.Print hTbl.getElementsByTagName("td").Item(2).innerText
        End If
    
    End Sub
    

    帖子示例

    Sub GetPriceByPost()
    
        Dim xHttp As MSXML2.XMLHTTP
        Dim hDoc As MSHTML.HTMLDocument
        Dim hDiv As HTMLDivElement
        Dim hTbl As HTMLTable
    
        Const sTICKER As String = "i=635957"
    
        Set xHttp = New MSXML2.XMLHTTP
    
        xHttp.Open "POST", "http://fonds.finanztreff.de/fonds_einzelkurs_uebersicht.htn"
        xHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
        xHttp.send sTICKER
    
        Do Until xHttp.readyState = 4
            DoEvents
        Loop
    
        If xHttp.Status = 200 Then
            Set hDoc = New MSHTML.HTMLDocument
            hDoc.body.innerHTML = xHttp.responseText
    
            'Get the third TD in the first TABLE in the first DIV whose class is 'tape'
            Set hDiv = hDoc.getElementsByClassName("tape").Item(0)
            Set hTbl = hDiv.getElementsByTagName("table").Item(0)
           Debug.Print hTbl.getElementsByTagName("td").Item(2).innerText
        Else
            Debug.Print xHttp.statusText
        End If
    
    End Sub
    

    【讨论】:

    • 感谢您向我解释 XMLHTTP 和 MSHTML。首先我还认为我可以使用 GET,但是如果我更改 sTICKER="DE000BP72DA4" 它会显示之前的价格,我认为 ?i= 参数也很重要。我还可以请您编辑您的答案并向我展示如何使用 POST 提交表单吗?你的回答很有帮助,谢谢
    • 如果我在网站上输入 DE000BP72DA4,我会得到相同的价格。我不会说德语,所以很难说出可能有什么不同。我不知道如何在该特定示例中使用 post,但我添加了另一个示例。我不确定为什么 POST 不能与 zertifikate.finanztreff.de/dvt_einzelkurs_uebersicht.htn 一起使用,而是与“喜欢...”一起使用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    相关资源
    最近更新 更多