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

如何使用Python+Selenium提取morningstar.com的表格数据

问题背景
  • 需求:抓取对应页面关键比率(Key ratio)表格中的ROE等财务数据
  • 故障现象:使用Selenium编写自动化脚本,执行iframe切换操作后依然无法定位目标元素,无法获取表格数据
  • 原实现代码:
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import time

url = 'https://www.morningstar.com/stocks/xnas/amzn/quote'
browser = webdriver.Firefox()
    
#Open the URL in browser
browser.get(url)
   
#####Click Key ratio button#####
#Wait until the Key ratio button is clickable
element = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="keyStats"]')))
#Click keyRatioBtn
element.click()
    
#####Click Full Key ratio url#####
#Wait until the Full Key ratio url is clickable
element = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, '//a[@class="sal-mds-link"]')))
#Click Full Key ratio url
element.click()
    
#####Get ROE list#####browser.implicitly_wait(20)    
time.sleep(5)
iframe = browser.find_elements(By.TAG_NAME, 'iframe')    
browser.switch_to.frame(1)
roeList = browser.find_element_by_xpath('//*[@id="tab-profitability"]')
print(roeList.get_attribute('innerHTML'))
故障根因

拿不到数据是多个逻辑错误叠加导致的:

  • 点击「完整关键比率」链接后,浏览器会新开标签页加载目标内容,原代码全程停留在初始的股票报价页操作,没有切换到新标签页,自然找不到对应元素
  • 硬编码iframe索引switch_to.frame(1)稳定性极差:页面加载过程中iframe的数量、排序会动态变化,靠序号选iframe大概率匹配到错误的iframe
  • 代码使用的find_element_by_xpath是Selenium旧版本的废弃API,Selenium 4+版本中该方法已被移除,运行时会直接抛出方法不存在的异常
  • 等待逻辑混乱:混用隐式等待和硬编码time.sleep(5),没有针对iframe、目标表格做显式等待,页面异步渲染的内容还没加载完成就执行查找,必然定位失败
  • 定位「完整关键比率」链接的XPath//a[@class="sal-mds-link"]匹配范围过宽,页面上存在多个同class的链接,很容易点错非目标元素
修复后代码

以下代码已经修复上述所有问题,可以直接运行获取目标数据:

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

url = 'https://www.morningstar.com/stocks/xnas/amzn/quote'
browser = webdriver.Firefox()
wait = WebDriverWait(browser, 15)

# 打开初始股票报价页
browser.get(url)

# 点击Key ratio入口按钮
key_stats_btn = wait.until(EC.element_to_be_clickable((By.ID, 'keyStats')))
key_stats_btn.click()

# 通过文本精准定位完整关键比率链接,避免点错
full_ratio_link = wait.until(EC.element_to_be_clickable(
    (By.XPATH, '//a[contains(normalize-space(text()), "Full Key Ratios")]')
))
full_ratio_link.click()

# 切换到最新打开的关键比率标签页
browser.switch_to.window(browser.window_handles[-1])

# 通过src特征定位加载比率数据的iframe,不依赖不稳定的索引
ratio_iframe = wait.until(EC.presence_of_element_located(
    (By.XPATH, '//iframe[contains(@src, "ratios/r.html")]')
))
browser.switch_to.frame(ratio_iframe)

# 等待盈利能力tab(含ROE数据)加载完成后获取内容
roe_tab = wait.until(EC.presence_of_element_located((By.ID, 'tab-profitability')))
print(roe_tab.get_attribute('innerHTML'))

# 数据抓取完成后可按需关闭浏览器
# browser.quit()
实现说明
  • 全流程使用显式等待替代硬编码sleep,既提升运行速度,也能适配不同网络环境下的页面加载速度,避免元素未加载就执行查找
  • iframe通过src路径特征匹配,不受页面iframe加载顺序、数量变化影响,定位更稳定
  • 所有元素定位均使用Selenium当前版本支持的标准API,不存在废弃方法报错问题
  • 标签页切换逻辑取窗口句柄列表的最后一个值,也就是最新打开的关键比率页面,不会出现在旧页面查找元素的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:24:16