You need to enable JavaScript to run this app. Python循环抓取雅虎财经出现Attribute Error (returning None)如何处理
优惠活动
大模型
产品
解决方案
定价
更多

Python循环抓取雅虎财经出现Attribute Error (returning None)如何处理

问题根因

你的随机报错核心是页面解析时soup.find()找不到对应元素返回了None,直接调用.text属性触发了AttributeError。报错的随机性来源于雅虎财经的反爬策略:请求频率过高时会随机返回验证码页、空白页或者结构异常的响应,原有元素选择器无法匹配到对应节点。

修复方案

你需要结合请求校验、异常捕获、请求限流三种机制处理,确保单只股票爬取失败不会中断整个程序:

  • 先校验请求返回状态码,非200状态直接跳过当前股票
  • 用try-except包裹单只股票的所有解析逻辑,捕获所有可能的解析异常
  • 每次请求后加随机延时,降低反爬触发概率
  • 可选:记录爬取失败的股票代码,后续统一补爬
修改后可运行代码
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import random

# 读取股票列表
df = pd.read_excel('ASX_Screen_Basic_Materials+Utilities+Energy+Industrials.xlsx')
# 存储结果和失败列表
result = []
failed_tickers = []

headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'}

for index, row in df.iterrows():
    ticker = str(row['Ticker'])
    print(f"正在爬取第{index+1}只股票:{ticker}")
    try:
        # 构造请求
        url = f'https://finance.yahoo.com/quote/{ticker}/profile?p={ticker}'
        r = requests.get(url, headers=headers, timeout=10)
        # 校验请求状态
        if r.status_code != 200:
            raise Exception(f"请求状态码异常:{r.status_code}")
        soup = BeautifulSoup(r.text, 'html.parser')

        # 解析字段
        description = soup.find('p',{'class': 'Mt(15px) Lh(1.6)'}).text
        name = soup.find('h3', {'class': 'Fz(m) Mb(10px)'}).text
        sector_span = soup.find('p', {'class': 'D(ib) Va(t)'}).find_all('span')
        sector = sector_span[1].text
        industry = sector_span[3].text

        # 存入结果
        result.append({
            '股票代码': ticker,
            '公司名称': name,
            '所属行业': industry,
            '所属板块': sector,
            '公司描述': description
        })
    except Exception as e:
        print(f"{ticker}爬取失败,原因:{str(e)}")
        failed_tickers.append(ticker)
    finally:
        # 随机延时1-3秒,避免触发反爬
        time.sleep(random.uniform(1,3))

# 导出结果到同一个Excel
result_df = pd.DataFrame(result)
result_df.to_excel('ASX股票信息汇总.xlsx', index=False)
# 导出失败列表
if failed_tickers:
    pd.DataFrame({'失败股票代码': failed_tickers}).to_excel('爬取失败列表.xlsx', index=False)

print(f"爬取完成:成功{len(result)}只,失败{len(failed_tickers)}只")
额外优化说明
  • 原代码分开导出4个Excel文件冗余,修改后所有字段存在同一个Excel的不同列,更便于使用
  • 新增了超时参数避免请求卡住,新增失败列表方便后续补爬
  • 请求头放在循环外避免重复构造,提升运行效率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 10:24:01