You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BeautifulSoup无法获取全部HTML数据 表格tbody内容缺失怎么办

问题根因

拿不到<tbody>内数据和BeautifulSoup的解析能力无关,核心原因是目标页面的表格内容为动态JS渲染:

  • 直接用requests发起请求拿到的只是页面初始静态HTML,此时目标表格的<tbody>要么是空占位标签,要么只包含少量框架代码,核心数据还未填充
  • 这类金融产品页的持仓、净值类表格,普遍采用前端异步加载逻辑:初始HTML只输出表格的表头、外壳等固定结构,等页面在浏览器端加载完成后,再通过异步接口拉取JSON格式的业务数据,最后由JS把数据拼接成DOM节点插入到<tbody>中,静态HTTP请求自然拿不到这部分动态生成的内容。
  • 验证方式很简单:把requests返回的r.text保存为本地HTML文件,直接用浏览器打开就能看到对应表格为空,和你用BeautifulSoup解析得到的结果完全一致。
可行解决方案

根据你的使用场景二选一即可:

方案1:直接请求后端数据接口(推荐,性能最优)

这是最高效的实现方式,不需要跑浏览器模拟渲染:

  • 打开浏览器开发者工具(F12),切换到「网络」面板,筛选Fetch/XHR类型请求
  • 刷新目标页面,在请求列表里查找返回内容包含表格字段(比如持仓名称、占比、净值等)的接口,这类接口一般返回JSON格式数据,路径通常包含holdings、fund-data、table类关键词
  • 直接用requests请求该接口即可拿到结构化的表格数据,不需要再做HTML解析

注意:部分接口会校验请求头的User-Agent、Referer字段,请求时把headers和浏览器请求头保持一致即可,一般不需要额外反爬破解。

方案2:使用JS渲染工具获取渲染完成的完整页面

如果接口参数复杂、不好复现,可以直接用能模拟浏览器执行JS的工具,等页面数据全部渲染完成后再提取HTML解析:

  • 常用工具可选playwright、selenium、requests-html,其中playwright的环境配置最简单,被反爬检测的概率更低
  • 参考实现代码:
from playwright.sync_api import sync_playwright
from bs4 import BeautifulSoup

target_url = "https://www.blackrock.com/br/products/251816/ishares-ibovespa-fundo-de-ndice-fund"

with sync_playwright() as p:
    # 启动无头浏览器
    browser = p.chromium.launch(headless=True)
    page = browser.new_page(
        user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
    )
    # 等待网络空闲状态,确认异步数据加载完成
    page.goto(target_url, wait_until="networkidle")
    full_html = page.content()
    browser.close()

soup = BeautifulSoup(full_html, "lxml")
# 定位目标表格,不建议硬编码索引,优先用class、外层容器id等固定属性定位
all_tables = soup.find_all("table")
target_table = all_tables[6]
优化建议
  • 不要硬编码表格索引(比如写死table[6]),只要前端页面稍微调整结构,索引就会失效,建议通过表格的专属class、上级容器的id等固定属性定位,代码稳定性会高很多
  • 这类金融站点对高频请求比较敏感,爬取时请添加合理的请求间隔,遵守站点robots规则,不要对站点服务造成压力。

内容的提问来源于stack exchange,提问作者Rafael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 07:09:27