首页 文章

Excel-VBA:在.aspx网页上抓取数据之前的按钮和下拉列表

提问于
浏览
1

我想使用VBA从网页上获取一个表,但我无法直接访问它,因为我需要从一个标签切换到另一个标签 . 问题依赖于网页的.aspx端(URL不会相应地发展) .

网址:http://www.morningstar.fr/fr/fundquickrank/default.aspx

Default page after clicking URL

Moving to "Long Terme" Tab - URL won't change

我已经设法构建了将表导出到Excel工作表的代码,但缺少“导航”部分 .

以下是关于点击“Long Terme Tab”按钮的HTML代码:

HTML Code Long Terme Tab

我的出发点在这里(ProcessHTMLPage进行表格刮擦):

Sub Browse_Morningstar()

Dim XMLPage As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument


XMLPage.Open "GET", "http://www.morningstar.fr/fr/fundquickrank/default.aspx", False
XMLPage.send

HTMLDoc.body.innerHTML = XMLPage.responseText


ProcessHTMLPage HTMLDoc

End Sub

我想这个请求必须以某种方式更新 . 对不起,如果我不够准确,但我对这一切都有点新意 .

非常感谢!

3 回答

  • 0
    Sub Get_Info()
    
    Dim Elems, e As Variant
    
    Const READYSTATE_COMPLETE& = 4&
    Dim ie As Object
    Set ie = Nothing
    DoEvents
    
    Set ie = CreateObject("InternetExplorer.Application")
    DoEvents
    
    With ie
        .Visible = True
        .Navigate "http://www.morningstar.fr/fr/fundquickrank/default.aspx"
        While Not .readyState = READYSTATE_COMPLETE
            DoEvents
        Wend
    End With
    
    With ie.Document
        Set Elems = .getElementsByTagName("span")
        DoEvents
        For Each e In Elems
            If e.getAttribute("onclick") = "__doPostBack('TabAction', '2')" Then
                e.Click
                'try to insert your table export code here
                Exit For
            End If
        Next e
    
    End With
    
    Set Elems = Nothing
    Set e = Nothing
    
    'ie.Quit Quit Internet Explorer once the exporting is done
    Set ie = Nothing
    
    MsgBox "Done"
    End Sub
    

    上面的代码直接导航到您想要的选项卡 . 尝试将它与您的代码结合起来导出表格,也许它会起作用 . ie.Visible = True只是为了确保你导航到正确的URL,但是一旦你看到它工作就把它弄错 . 希望能帮助到你!

  • 0

    如果您希望使用IE从该目标页面获取表格数据,那么这就是实现这一目标的一种方式 .

    Sub Fetch_Data()
        Dim IE As New InternetExplorer, html As HTMLDocument
        Dim posts As Object, post As Object, elem As Object, trow As Object
    
        With IE
            .Visible = True
            .navigate "http://www.morningstar.fr/fr/fundquickrank/default.aspx"
            While .readyState < 4: DoEvents: Wend
            Set html = .document
        End With
    
        For Each post In html.getElementsByClassName("ms_tab_inactivetext")
            If InStr(post.innerText, "Long terme") > 0 Then post.ParentNode.Click: Exit For
        Next post
    
        Do While IE.Busy = True Or IE.readyState <> 4: DoEvents: Loop
    
        Set posts = html.getElementById("ctl00_ctl00_MainContent_Layout_1MainContent_gridResult")
    
        For Each elem In posts.Rows
            For Each trow In elem.Cells
                c = c + 1: Cells(r + 1, c) = trow.innerText
            Next trow
            c = 0: r = r + 1
        Next elem
        IE.Quit
    End Sub
    

    参考添加到库:

    1. Microsoft HTML Object Library
    2. Microsoft Internet Controls
    
  • 0

    __doPostBack和onclick事件:

    当您检查与选择主内容div栏相关联的HTML时,例如 Long Terme ,您可以看到与各个条形项目的 onclick 事件关联的java脚本__doPostBack function .

    Observe the HTML in question:

    __doPostBack

    引用上面的链接:

    该函数采用以下两个参数:eventTarget - 它包含导致回发的控件的ID . eventArgument - 包含与控件关联的任何其他数据 . 在任何ASP.NET页面中,都会自动声明两个隐藏字段:__ EVENTTARGET和__EVENTARGUMENT . 当页面回发到服务器时,ASP.NET检查__EVENTTARGET和__EVENTARGUMENT值,这样它就可以决定哪些控件导致页面被回发以及必须处理的事件是什么 .

    tldr;

    ASP 的"olden"天中,通常必须有一个表单来捕获用户输入,然后创建其他页面以接受这些输入( GETPOST ),验证,执行操作等 . 使用 ASP.NET ,您可以在接受上述参数的服务器上声明控件,并在检查了值之后回发到同一页面 .

    第一个参数告诉您哪个控件被触发,第二个参数提供了附加信息,在这种情况下,它确定返回哪些选项卡信息 .

    从上面我们可以看出 TabAction 是控件,并且其后面的数字对应于感兴趣的标签,例如2为Long Terme(为0 - 索引) .

    在VBA中,我们可以通过多种方式执行此JS函数,但我将使用:

    .document.parentWindow.execScript "__doPostBack('EVENTTARGET', 'EVENTARGUMENT')"
    

    这变为:

    .document.parentWindow.execScript "__doPostBack('TabAction', '2')"
    

    我将其重新编写为接受EVENTARGUMENT作为常量 OPTION_CHOSEN ,因此可以通过更改顶部的值来检索不同的选项卡 .

    执行该函数后,剩下一点时间来刷新页面,然后该表被 id 抓取:

    Set hTable = .document.getElementById("ctl00_ctl00_MainContent_Layout_1MainContent_gridResult")
    

    然后,表沿着行和列循环(列是沿着每行长度的表格单元格) .


    Examples from page:

    Page


    代码输出示例:

    Example code output


    Full code:

    Option Explicit
    Public Sub GetTable()
        Dim IE As New InternetExplorer
        Const OPTION_CHOSEN As Long = 2             '0 Aperçu; 1 Court terme; 2 Long terme; 3 Portefeuille; 4 Frais & Détails
    
        Application.ScreenUpdating = True
        With IE
            .Visible = True
            .navigate "http://www.morningstar.fr/fr/fundquickrank/default.aspx"
            While .readyState < 4: DoEvents: Wend
    
            .document.parentWindow.execScript "__doPostBack('TabAction', ' " & OPTION_CHOSEN & "')"
    
            Do While .Busy = True Or .readyState <> 4: DoEvents: Loop
    
            Dim hTable As HTMLTable, tRow As HTMLTableRow, tCell As HTMLTableCell
    
            Set hTable = .document.getElementById("ctl00_ctl00_MainContent_Layout_1MainContent_gridResult")
            Dim c As Long, r As Long
            With ActiveSheet
                For Each tRow In hTable.Rows
                    For Each tCell In tRow.Cells
                        c = c + 1: .Cells(r + 1, c) = tCell.innerText
                    Next tCell
                    c = 0: r = r + 1
                Next tRow
                .Columns("A:A").Delete
                .UsedRange.Columns.AutoFit
            End With
            .Quit
        End With
        Application.ScreenUpdating = True
    End Sub
    

    References (VBE > Tools > References):

    • Microsoft Internet Controls

相关问题