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

如何用Python的BeautifulSoup4爬取相邻兄弟节点数据(AAPL Basic EPS)

问题:爬取雅虎财经AAPL的Basic EPS数值失败

尝试用Python脚本从https://finance.yahoo.com/quote/AAPL/financials爬取AAPL的Basic EPS行数据时,原代码多次打印“Basic EPS”但无法获取相邻的数值字段。

原代码

#!/usr/bin/env python3
import os, pandas as pd
from os import chdir
#Web scraping
from bs4 import BeautifulSoup
import urllib.request as ul

chdir(os.getcwd()+"/Data")
colist="AAPL"

header = {'User-Agent': 'Mozilla/5.0'} #prevents a 403 error
req=ul.Request("https://finance.yahoo.com/quote/"+colist+"/financials", headers=header)
page = ul.urlopen(req)
soup=BeautifulSoup(page, "lxml")

 for div_parent in soup.find("div",class_="rowTitle svelte-1xjz32c",title="Basic EPS"):
     print(div_parent.text)
     for div_child in div_parent.find_next_siblings("div",class_="column svelte-1xjz32c"):
          print(div_child.text)

页面相关HTML结构

<div class="row lv-0 svelte-1xjz32c"><div class="column sticky svelte-1xjz32c"> <div class="rowTitle svelte-1xjz32c" title="Basic EPS">Basic EPS</div></div> <div class="column svelte-1xjz32c alt">6.46 </div><div class="column svelte-1xjz32c">6.16 </div><div class="column svelte-1xjz32c alt">6.15 </div><div class="column svelte-1xjz32c">5.67 </div><div class="column svelte-1xjz32c alt">3.31 </div></div>  <div class="row lv-0 svelte-1xjz32c"><div class="column sticky svelte-1xjz32c"> <div class="rowTitle svelte-1xjz32c" title="Diluted EPS">Diluted EPS</div></div> <div class="column svelte-1xjz32c alt">6.43 </div><div class="column svelte-1xjz32c">6.13 </div><div class="column svelte-1xjz32c alt">6.11 </div><div class="column svelte-1xjz32c">5.61 </div><div class="column svelte-1xjz32c alt">3.28 </div></div>

解决思路与代码调整方案

问题分析

原代码的核心错误:

  • soup.find(...) 获取的是"Basic EPS"文本所在的rowTitle元素,直接遍历该元素会遍历其内部的文本节点,导致重复打印"Basic EPS"
  • 数值字段并不在rowTitle的兄弟节点中,而是在rowTitle的父级容器(column sticky)的同级节点里,所有数值和标题都属于同一个row容器。

正确思路

  1. 定位到包含"Basic EPS"的rowTitle元素
  2. 向上遍历DOM树,找到该元素所在的最外层row容器(class为row lv-0 svelte-1xjz32c)
  3. 在这个row容器内,筛选所有非sticky类型的column元素,提取它们的文本内容,即为目标EPS数值

调整后的代码

#!/usr/bin/env python3
import os
import pandas as pd
from os import chdir
from bs4 import BeautifulSoup
import urllib.request as ul

# 切换到Data目录(目录不存在则创建)
try:
    chdir(os.path.join(os.getcwd(), "Data"))
except FileNotFoundError:
    os.mkdir("Data")
    chdir("Data")

colist = "AAPL"

header = {'User-Agent': 'Mozilla/5.0'}
req = ul.Request(f"https://finance.yahoo.com/quote/{colist}/financials", headers=header)
page = ul.urlopen(req)
soup = BeautifulSoup(page, "lxml")

# 1. 找到Basic EPS对应的rowTitle元素
basic_eps_title = soup.find("div", class_="rowTitle svelte-1xjz32c", title="Basic EPS")
if basic_eps_title:
    # 2. 向上找到所在的row容器(rowTitle -> column sticky -> row)
    row_container = basic_eps_title.parent.parent
    # 3. 提取所有非sticky的column元素的文本,去除空格
    eps_values = [col.get_text(strip=True) for col in row_container.find_all("div", class_="column svelte-1xjz32c") if "sticky" not in col.get("class", [])]
    
    print("Basic EPS数值:")
    for val in eps_values:
        print(val)
else:
    print("未找到Basic EPS对应的行")

代码说明

  • 增加目录异常处理,避免因Data目录不存在导致报错
  • 通过parent.parent直接定位到row容器,匹配HTML结构层级
  • 用列表推导式筛选非sticky的column元素,同时清理数值前后的空格
  • 增加元素存在性判断,避免空指针异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 08:05:24