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

如何用Python抓取IEA桑基图网页数据?(BS、Selenium尝试未果)

解决IEA桑基图数据抓取问题

问题根源

你用BeautifulSoup抓不到数据,核心原因是页面的桑基图数据不是静态嵌入HTML的——页面加载完成后才会通过JavaScript调用后端API拉取数据,requests.get只能拿到初始的空壳HTML,自然拿不到动态加载的内容。

方案1:直接调用API获取数据(推荐)

这个网站的桑基图数据是通过公开API返回的JSON格式,直接请求API比模拟浏览器高效得多,也更稳定。

操作步骤

  • 打开浏览器F12开发者工具,切换到「Network」标签页,刷新页面;
  • 筛选「XHR」类型请求,找到名称类似balance?country=Indonesia的请求,复制其接口地址;
  • 用Python的requests库直接请求该接口,解析返回的JSON数据。

示例代码

import requests

# 对应Indonesia的Balance数据API接口
api_url = "https://www.iea.org/api/sankey/balance?country=Indonesia"
# 模拟浏览器请求头,避免被拦截
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
}

response = requests.get(api_url, headers=headers)
if response.status_code == 200:
    data = response.json()
    # 打印数据结构,按需提取字段
    print("数据结构:")
    print(data.keys())
    # 提取节点数据
    print("\n节点信息:")
    for node in data['nodes']:
        print(f"ID: {node['id']}, 名称: {node['name']}, 数值: {node['value']}")
    # 提取链路数据(桑基图的流向关系)
    print("\n链路信息:")
    for link in data['links']:
        print(f"从 {link['source']} 到 {link['target']}, 流量: {link['value']}")
else:
    print(f"请求失败,状态码:{response.status_code}")

方案2:用Selenium正确获取动态数据

如果一定要用Selenium,关键是要等页面完全加载,确保数据元素生成后再抓取。

示例代码

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.iea.org/sankey/#?c=Indonesia&s=Balance"

# 初始化Chrome浏览器(需提前下载对应版本的chromedriver)
driver = webdriver.Chrome()
driver.get(url)

try:
    # 最多等待10秒,直到桑基图数据元素出现
    wait = WebDriverWait(driver, 10)
    sankey_data = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "sankey-data")))
    
    # 打印数据文本
    print(sankey_data.text)
    
    # 更高效的方式:直接执行JS获取页面中的数据对象
    raw_data = driver.execute_script("return window.sankeyData;")
    print("\n原始JSON数据:")
    print(raw_data)
finally:
    # 关闭浏览器
    driver.quit()

后续处理

拿到JSON数据后,你可以用pandas库把它转换成表格格式,比如:

import pandas as pd

# 把节点数据转成DataFrame
nodes_df = pd.DataFrame(data['nodes'])
# 把链路数据转成DataFrame
links_df = pd.DataFrame(data['links'])

print("节点表格:")
print(nodes_df)
print("\n链路表格:")
print(links_df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:53:17