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

时间:2018-01-13 17:46:50

标签: html excel vba excel-vba web-scraping

我想使用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 :(得分:1)

__ doPostBack和onclick事件:

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

观察相关HTML:

__doPostBack

引用我上面的链接:

  

该函数采用以下两个参数:

     

eventTarget - 包含导致该控件的控件的ID   回帖。 eventArgument - 包含任何其他数据   与控制相关联。

     

在任何ASP.NET页面中有两个隐藏字段:__ EVENTTARGET和   自动声明__EVENTARGUMENT。当页面回发到服务器时,ASP.NET会检查__EVENTTARGET和__EVENTARGUMENT   值和这样它可以决定哪个控件导致了   要回发的页面以及必须处理的事件。

tldr;

在" olden" ASP天通常必须有一个表单来捕获用户输入,然后创建其他页面以接受这些输入(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")

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

来自页面的示例:

Page

代码输出中的示例:

Example code output

完整代码:

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

参考文献(VBE&gt;工具&gt;参考文献):

  1. Microsoft Internet Controls

答案 1 :(得分: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,但是一旦你看到它工作就把它弄错。希望它有所帮助!

答案 2 :(得分: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