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

Python导出Yahoo Finance爬取的HTML表格至CSV异常问题排查

爬取Yahoo Finance数据导出CSV异常问题排查

问题描述

通过Python爬取Yahoo Finance的关键统计HTML表格,终端打印内容正常,但导出CSV文件时结果异常。

原代码

import requests
from bs4 import BeautifulSoup
import csv
import pandas as pd

mystocks = ["XOM", "CVX", "COP", "EOG"]
stockdata = []

def getData(symbol): 
    headers = {"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0"}
    url = f"https://finance.yahoo.com/quote/{symbol}/key-statistics"
    soup = BeautifulSoup(requests.get(url, headers=headers).content, "html.parser")
    print("Ticker - "+symbol)
    for t in soup.select("table"):
        for tr in t.select("tr:has(td)"):
            for sup in tr.select("sup"):
                sup.extract()
            stockdata = [td.get_text(strip=True) for td in tr.select("td")]
            if len(stockdata) == 2:
                print("{:<50} {}".format(*stockdata))

for item in mystocks:
    stockdata.append(getData(item))

    df = pd.DataFrame(stockdata)
    df.to_csv('file_name.csv')

问题分析

  • 函数无返回值:getData仅打印数据,未返回任何内容,导致stockdata.append(getData(item))每次添加的都是None,最终CSV全是空值。
  • 局部变量覆盖全局变量:函数内部定义了与全局重名的stockdata变量,爬取到的键值对无法存入全局列表。
  • CSV写入时机错误:在循环内每处理一只股票就写入CSV,数据未完全收集就覆盖写入,最终内容不完整。
  • 数据结构不规范:未将单只股票的统计数据整理成结构化格式,无法生成规整的DataFrame,导致CSV格式混乱。

修复后的代码

import requests
from bs4 import BeautifulSoup
import pandas as pd

mystocks = ["XOM", "CVX", "COP", "EOG"]
stockdata = []

def getData(symbol): 
    headers = {"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0"}
    url = f"https://finance.yahoo.com/quote/{symbol}/key-statistics"
    soup = BeautifulSoup(requests.get(url, headers=headers).content, "html.parser")
    print("Ticker - "+symbol)
    # 用字典存储单只股票的所有统计数据,先存入股票代码
    stock_stats = {"Ticker": symbol}
    for t in soup.select("table"):
        for tr in t.select("tr:has(td)"):
            for sup in tr.select("sup"):
                sup.extract()
            td_texts = [td.get_text(strip=True) for td in tr.select("td")]
            if len(td_texts) == 2:
                key, value = td_texts
                stock_stats[key] = value
                print("{:<50} {}".format(key, value))
    # 返回结构化的股票统计数据
    return stock_stats

# 遍历所有股票,收集完整数据
for item in mystocks:
    stats = getData(item)
    stockdata.append(stats)

# 生成DataFrame并导出CSV,关闭索引列避免冗余内容
df = pd.DataFrame(stockdata)
df.to_csv('stock_statistics.csv', index=False)

修复说明

  • 返回结构化数据:getData返回包含股票代码和所有统计项的字典,确保数据能被正确收集到全局列表中。
  • 避免变量冲突:将函数内的局部变量重命名为td_texts和stock_stats,不再覆盖全局的stockdata。
  • 调整写入时机:在所有股票数据收集完成后再生成DataFrame并导出CSV,保证数据完整。
  • 规范数据结构:用字典存储单只股票的所有数据,生成的DataFrame会自动将统计项设为列、股票设为行,输出的CSV格式规整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:00:17