如何用Python抓取Xe网站动态汇率折线图数据?
可行的XE汇率图表数据抓取方案
一、基于Requests的API修正方案
你之前使用的API缺少时间范围和分辨率参数,这是导致返回数据与图表不符的核心原因。正确的API请求需要指定以下关键参数:
fromCurrency/toCurrency:目标货币对(如SGD/USD)startTime:时间范围起始毫秒时间戳endTime:时间范围结束毫秒时间戳resolution:数据分辨率,对应不同时间周期:- 5年周期对应
resolution=MONTHLY - 1年对应
WEEKLY,1个月对应DAILY等
- 5年周期对应
同时需要补充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__中),步骤如下:
- 加载目标页面并等待图表渲染完成
- 执行JS代码提取全局数据变量
- 解析数据并整理为表格格式
示例脚本:
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
相关产品推荐
相关产品推荐

