__doPostBack 和 onclick 事件:
当您检查与选择主要内容 div 栏相关的 HTML 时,例如Long Terme,您可以看到有一个 java 脚本 __doPostBack function 与各个条形项目的 onclick 事件相关联。
观察有问题的 HTML:
引用我上面的链接:
该函数接受以下两个参数:
eventTarget - 这包含导致
回帖。 eventArgument - 这包含任何附加数据
与控件相关联。
在任何 ASP.NET 页面中,两个隐藏字段:__EVENTTARGET 和
__EVENTARGUMENT 是自动声明的。当页面回发到服务器时,ASP.NET 检查 __EVENTTARGET 和 __EVENTARGUMENT
值,这样它就可以决定是哪个控件导致了
要回发的页面以及必须处理的事件。
tldr;
在 ASP 的“旧”时代,通常必须有一个表单来捕获用户输入,然后创建更多页面来接受这些输入(GET 或 POST)、验证、执行操作等.使用ASP.NET,您可以在服务器上声明接受上述参数的控件,并在检查
的值后发回同一页面
第一个参数告诉您哪个控件被触发,第二个参数提供附加信息,在这种情况下决定返回哪些选项卡信息。
我们可以从上面看到TabAction 是控件,它后面的数字对应于感兴趣的选项卡,例如2 表示长期(作为 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")
然后表格沿着它的行和列循环(列是沿着每行长度的表格单元格)。
页面示例:
代码输出示例:
完整代码:
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 > 工具 > 参考资料):
- Microsoft Internet 控件