vba 网页数据抓取(使用ASP.NET从网页中获取表格,无法直接访问它)
优采云 发布时间: 2021-10-18 12:18vba 网页数据抓取(使用ASP.NET从网页中获取表格,无法直接访问它)
问题
我想使用 VBA 从网页中获取表格,但我无法直接访问它,因为我需要从一个选项卡切换到另一个选项卡。问题取决于网页的 .aspx 结尾(URL 不会相应发展)。
网址:.aspx
点击网址后的默认页面
移至“长期”选项卡-URL 不会更改
我设法构建了将表导出到 Excel 工作表的代码,但缺少“导航”部分。
以下是与点击“长期标签”按钮相关的 HTML 代码:
HTML代码“长代码”标签
我的起点在这里(ProcessHTMLPage for table crawling):
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
我认为必须以某种方式更新请求。对不起,如果我不够准确,但我有点新。
非常感谢!
解决方案
__ doPostBack 和 onclick 事件:
当您查看与选择主要内容div列相关的HTML时,例如Long Terme,您会看到有一个与单个列项的onclick事件相关联的Java脚本__doPostBack函数。
观察相关的 HTML:
引用我上面的链接:
该函数采用以下两个参数:
eventTarget-this 收录回发的原因。eventArgument-this 收录与控件关联的任何其他数据。
在任何 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>工具>参考):
微软互联网控制