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

如何用Python提取URL特定表格:pd.read_html未识别表格解决方法

问题原因

pd.read_html() 仅能解析初始静态HTML源码中存在的<table>标签,你访问的iShares产品页持仓表格是页面加载完成后通过JavaScript异步拉取数据动态渲染生成的,直接用requests请求拿到的初始页面源码里根本没有持仓表格的DOM结构,自然会提示找不到表格。

推荐方案:直接调用站点公开数据接口

不需要模拟浏览器渲染,iShares的产品持仓数据通过固定异步接口返回结构化数据,构造合法请求即可直接拿到全量持仓,速度快稳定性高:

  • 接口支持直接返回CSV格式数据,无需解析DOM
  • 请求必须携带正常浏览器的User-Agent,否则会被反爬拦截
  • CSV开头包含几行产品说明文本,读取时需要跳过才能正确识别表头
import pandas as pd
import requests
from io import StringIO

# 目标ETF持仓数据接口
holdings_api = "https://www.ishares.com/de/privatanleger/de/produkte/251931/ishares-stoxx-europe-600-ucits-etf-de-fund/1467271812596.ajax"
# 请求参数,指定返回CSV格式的全量持仓数据
req_params = {
    "fileType": "csv",
    "dataType": "fund",
    "productId": "251931"
}
# 请求头模拟普通浏览器访问
req_headers = {
    "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"
}

response = requests.get(holdings_api, params=req_params, headers=req_headers)
response.encoding = "utf-8"
# 跳过开头2行非数据说明,读取持仓数据
holdings_df = pd.read_csv(StringIO(response.text), skiprows=2)
# 清洗空行和尾部汇总行
holdings_df = holdings_df.dropna(subset=["Emittententicker", "Name"]).reset_index(drop=True)
# 导出为xlsx文件
holdings_df.to_excel("ishares_stoxx_europe_600_holdings.xlsx", index=False)
print("持仓数据提取完成,已保存至本地文件")
备选方案:动态渲染页面后解析

如果后续接口规则变动,可以用支持JS渲染的工具加载完整页面后再提取表格,以requests-html为例:

  • 先安装依赖:pip install requests-html pandas openpyxl
  • 渲染页面时等待表格元素加载完成,再调用pd.read_html解析
from requests_html import HTMLSession
import pandas as pd

page_url = 'https://www.ishares.com/de/privatanleger/de/produkte/251931/ishares-stoxx-europe-600-ucits-etf-de-fund'
session = HTMLSession()
resp = session.get(
    page_url,
    headers={"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"}
)
# 等待JS渲染完成,超时时间设为20秒
resp.html.render(timeout=20)
# 解析页面内所有表格
all_tables = pd.read_html(resp.html.html)
# 匹配包含持仓列名的目标表格
for table in all_tables:
    if "Gewichtung (%)" in table.columns and "Name" in table.columns:
        holdings_df = table
        break
holdings_df.to_excel("etf_holdings.xlsx", index=False)

注意:不要高频请求目标站点,避免被IP封禁;如果渲染后仍找不到表格,可以适当延长render等待时间,或显式指定等待持仓表格对应的CSS选择器加载完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 15:39:16