VBA如何抓取仅在审查元素显示、网页源代码不存在的动态标签季度数据?
解决方案
问题根因
- 你当前爬取的是页面初始加载的静态内容,该网站默认展示年度数据,季度数据是点击「按季度」标签后通过AJAX动态请求加载的,会直接替换同ID容器
divHoSoCongTyAjax内的内容,所以静态请求初始URL只能拿到年度数据。 - 两类数据共享容器ID是因为前端逻辑是请求不同数据后直接覆盖同个容器的内容,不是同时存在两套DOM。
方案1:直接请求季度数据接口(推荐,效率最高)
你可以直接调用页面加载季度数据的后端接口,不需要解析主页面内容:
- 打开浏览器F12开发者工具,切换到「网络」面板,筛选「XHR/ fetch」请求
- 点击页面上的「按季度」标签,就能捕获到对应的接口请求,调整请求参数里的
ReportType为季度对应的取值即可拿到季度数据的HTML片段
修改后的VBA代码示例:
Sub GetQuarterData() Dim html As HTMLDocument Set html = New HTMLDocument ' 季度数据接口,参数说明:ReportType=1对应季度,=2对应年度,symbol对应股票代码 Const QUARTER_API_URL As String = "https://s.cafef.vn/Ajax/HoSoCongTy/BaoCaoTaiChinh.ashx?symbol=VCB&type=1&Doctype=1&ReportType=1&Unit=1&Year=0&PageIndex=0&PageSize=4" With CreateObject("MSXML2.XMLHTTP") .Open "GET", QUARTER_API_URL, False .SetRequestHeader "User-Agent", "Mozilla/5.0" .SetRequestHeader "Referer", "https://s.cafef.vn/hose/VCB-ngan-hang-thuong-mai-co-phan-ngoai-thuong-viet-nam.chn" .send html.body.innerHTML = .responseText End With ' 此时获取的td就是季度数据 Debug.Print html.getElementsByTagName("td")(23).innerText Debug.Print html.getElementsByTagName("td")(24).innerText Debug.Print html.getElementsByTagName("td")(25).innerText Debug.Print html.getElementsByTagName("td")(26).innerText Set html = Nothing End Sub
方案2:模拟浏览器操作(适合不想分析接口的场景)
如果不想抓接口,可以用Selenium Basic或者IE自动化对象模拟真实用户操作:打开页面→点击按季度按钮→等待数据加载完成后再提取内容,示例用IE对象的代码如下:
Sub GetQuarterDataWithIE() Dim ie As Object Dim html As HTMLDocument Set ie = CreateObject("InternetExplorer.Application") ie.Visible = False ' 设为True可以看到浏览器操作过程 ie.navigate "https://s.cafef.vn/hose/VCB-ngan-hang-thuong-mai-co-phan-ngoai-thuong-viet-nam.chn" ' 等待页面加载完成 Do While ie.readyState <> 4 Or ie.Busy: DoEvents: Loop Set html = ie.document ' 模拟点击按季度按钮,可按实际页面的按钮类名或ID调整选择器 html.querySelector(".tab-quater").Click ' 等待数据加载完成 Application.Wait Now + TimeValue("00:00:02") ' 提取季度数据 Debug.Print html.getElementById("divHoSoCongTyAjax").getElementsByTagName("td")(23).innerText ie.Quit Set ie = Nothing Set html = Nothing End Sub
内容的提问来源于stack exchange,提问作者Cao Doremi
相关产品推荐
相关产品推荐

