无法从CME FedWatch工具交互式折线图提取目标利率概率值
问题描述
需要从CME FedWatch工具提取13 Dez23和Historical条件下,交互式折线图中仅鼠标悬停才显示的Target Rate Probability百分比值。
此前尝试的方法均失效:
- 使用WebDriverWait等待元素加载,触发
TimeoutException - 通过JS修改元素
display/visibility属性,报错Cannot read properties of null (reading 'style'),因XPath定位的元素不存在 - 模拟鼠标悬停的代码无法找到目标元素,因为使用了动态生成的CSS选择器(如
#highcharts-986wlrn-17)
问题根源
- 动态元素ID:Highcharts生成的图表容器ID为随机值,硬编码定位必然失效
- 动态iframe:目标内容所在的iframe ID会随页面刷新变化,固定ID切换会失败
- 低效的模拟操作:鼠标悬停获取tooltip属于间接方式,实际数据已存在于页面的Highcharts配置对象中
解决方案
直接通过JavaScript读取Highcharts的原始数据,无需模拟鼠标操作,步骤如下:
- 通过iframe的src属性动态定位并切换到目标iframe
- 选择目标日期(13 Dez23)和Historical模式
- 执行JS提取Highcharts图表的series数据,包含完整的日期与概率对应关系
完整代码
from webdriver_manager.chrome import ChromeDriverManager 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 time # 初始化浏览器 driver = webdriver.Chrome(executable_path=ChromeDriverManager().install()) driver.get('https://www.cmegroup.com/markets/interest-rates/cme-fedwatch-tool.html') driver.maximize_window() # 等待并切换到动态iframe(通过src包含fedwatch定位) wait = WebDriverWait(driver, 20) iframe = wait.until(EC.presence_of_element_located((By.XPATH, "//iframe[contains(@src, 'fedwatch')]"))) driver.switch_to.frame(iframe) # 选择目标日期:13 Dez23(下拉菜单第8个选项,若位置变化需调整) wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#ctl00_MainContent_ucViewControl_IntegratedFedWatchTool_ddlMeetingDates + div a"))).click() wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#ctl00_MainContent_ucViewControl_IntegratedFedWatchTool_ddlMeetingDates + div ul li:nth-child(8) a"))).click() time.sleep(3) # 切换到Historical模式 wait.until(EC.element_to_be_clickable((By.ID, "ctl00_MainContent_ucViewControl_IntegratedFedWatchTool_lbHistorical"))).click() time.sleep(5) # 执行JavaScript提取Highcharts图表数据(以175-200利率区间为例) script = """ const charts = Highcharts.charts; for (let chart of charts) { if (chart && chart.series.length > 0) { // 筛选对应目标利率区间的series const targetSeries = chart.series.find(s => s.name.includes('175-200')); if (targetSeries) { return targetSeries.data.map(point => ({ date: new Date(point.x).toLocaleDateString('en-US', {weekday: 'short', month: 'long', day: 'numeric', year: 'numeric'}), probability: point.y.toFixed(2) + '%' })); } } } return []; """ probability_data = driver.execute_script(script) # 输出结果 print("175-200目标利率概率数据:") for item in probability_data: print(f"{item['date']}: {item['probability']}") driver.quit()
代码说明
- 动态iframe定位:通过
contains(@src, 'fedwatch')匹配iframe,避免动态ID的影响 - 日期选择:通过CSS选择器定位下拉菜单,选择对应13 Dez23的选项(若日期选项位置变化,需调整
li:nth-child(8)的数字) - 数据提取:直接读取Highcharts的
series数据,每个数据点包含时间戳(point.x)和概率值(point.y),无需模拟鼠标悬停 - 灵活性:若需要其他利率区间的概率,修改
series.find(s => s.name.includes('XXX'))中的关键词即可
内容的提问来源于stack exchange,提问作者linus otte
相关产品推荐
相关产品推荐

