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

如何用Python抓取Xe网站动态汇率折线图数据?

可行的XE汇率图表数据抓取方案

一、基于Requests的API修正方案

你之前使用的API缺少时间范围和分辨率参数,这是导致返回数据与图表不符的核心原因。正确的API请求需要指定以下关键参数:

  • fromCurrency/toCurrency:目标货币对(如SGD/USD)
  • startTime:时间范围起始毫秒时间戳
  • endTime:时间范围结束毫秒时间戳
  • resolution:数据分辨率,对应不同时间周期:
    • 5年周期对应resolution=MONTHLY
    • 1年对应WEEKLY,1个月对应DAILY等

同时需要补充User-Agent和Referer头避免被拦截,authorization头若失效可从浏览器Network请求中复制最新值。修正后的脚本示例:

import requests
import pandas as pd
import os
from datetime import datetime, timedelta

# 计算5年时间范围的毫秒时间戳
end_time = int(datetime.now().timestamp() * 1000)
start_time = int((datetime.now() - timedelta(days=5*365)).timestamp() * 1000)

# 构造带完整参数的API请求地址
data_url = (
    f"https://www.xe.com/api/protected/charting-rates/"
    f"?fromCurrency=SGD&toCurrency=USD&startTime={start_time}&endTime={end_time}"
    f"&resolution=MONTHLY&crypto=false"
)

# 构造请求头
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
    'Referer': 'https://www.xe.com/currencycharts/?from=SGD&to=USD&view=5Y',
    'authorization': 'Basic bG9kZXN0YXI6cHVnc25heA=='  # 失效时从浏览器Network请求复制最新值
}

response = requests.get(data_url, headers=headers)
if response.status_code == 200:
    try:
        response_data = response.json()
        values_list = []
        for batch in response_data['batchList']:
            batch_start = datetime.fromtimestamp(batch['startTime'] / 1000)
            interval = timedelta(milliseconds=batch['interval'])
            for idx, rate in enumerate(batch['rates']):
                # 计算每个数据点的具体时间
                point_time = batch_start + interval * idx
                values_list.append({
                    'Timestamp': point_time,
                    'Rate': rate
                })
        
        df = pd.DataFrame(values_list)
        csv_path = os.path.join(os.getcwd(), 'SGDToUSD_5Y.csv')
        df.to_csv(csv_path, index=False)
        print(f"数据已保存到 {csv_path}")
    except Exception as e:
        print(f"解析错误: {str(e)}")
else:
    print(f"请求失败,状态码: {response.status_code}")

二、基于Selenium的可靠数据提取方案

无需鼠标悬停,直接从页面的全局JavaScript变量中提取数据(XE基于Next.js构建,数据通常存储在window.__NEXT_DATA__中),步骤如下:

  1. 加载目标页面并等待图表渲染完成
  2. 执行JS代码提取全局数据变量
  3. 解析数据并整理为表格格式

示例脚本:

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
import pandas as pd
import os
import json

driver = webdriver.Chrome()
driver.get("https://www.xe.com/currencycharts/?from=SGD&to=USD&view=5Y")

# 等待图表容器加载完成
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CLASS_NAME, 'sc-61e76e6d-0'))
)

# 提取Next.js全局数据
next_data = driver.execute_script("return window.__NEXT_DATA__")
# 定位图表汇率数据
chart_data = next_data['props']['pageProps']['chartData']

values_list = []
for batch in chart_data['batchList']:
    batch_start = pd.to_datetime(batch['startTime'], unit='ms')
    interval = pd.Timedelta(milliseconds=batch['interval'])
    for idx, rate in enumerate(batch['rates']):
        point_time = batch_start + interval * idx
        values_list.append({
            'Timestamp': point_time,
            'Rate': rate
        })

df = pd.DataFrame(values_list)
csv_path = os.path.join(os.getcwd(), 'SGDToUSD_Selenium.csv')
df.to_csv(csv_path, index=False)
print(f"数据已保存到 {csv_path}")

driver.quit()

注意事项

  • API的authorization头可能定期更新,请求失败时可从浏览器开发者工具的Network标签复制最新值
  • Selenium方案需确保浏览器驱动与浏览器版本匹配
  • 避免高频请求,防止触发网站反爬机制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:55:15