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

通过for循环批量获取DataFrames时遭遇AttributeError问题求助

批量爬取东方财富网高管持股数据报错修复

问题背景

单只股票(如000001)可通过以下代码正常获取高管持股DataFrame:

import pandas as pd
import requests

df = pd.DataFrame(
    requests.get('https://datacenter-web.eastmoney.com/api/data/v1/get?reportName=RPT_EXECUTIVE_HOLD_DETAILS&columns=ALL&filter=(SECURITY_CODE%3D"000001")')\
        .json().get('result').get('data'))
print(df)

但遍历股票代码列表target_list_onlynumber批量爬取时,执行以下代码报错:

df_list = []
for i in target_list_onlynumber:
    exec_data = requests.get('https://datacenter-web.eastmoney.com/api/data/v1/get?reportName=RPT_EXECUTIVE_HOLD_DETAILS&columns=ALL&filter=(SECURITY_CODE%3D"{i}")')\
        .json().get('result').get('data')
    df_i = pd.DataFrame(exec_data)
    df_list.append(df_i)
    print(df_i)

报错核心信息:

AttributeError: 'NoneType' object has no attribute 'get'

错误出在.json().get('result').get('data'),说明get('result')返回了None,无法继续调用get('data')。

报错原因分析

  1. 字符串格式化错误:原代码用单引号包裹URL,其中的{i}不会被Python解析为变量,请求的URL实际把"{i}"作为股票代码传给服务器,服务器返回无结果响应,导致result为None。
  2. 反爬机制触发:批量请求频率过高,网站服务器拒绝返回正常数据,响应不是预期JSON格式,解析后无result字段。
  3. 部分股票无数据:部分股票可能没有高管持股记录,接口返回的JSON中result本身就是None。

修复后的代码

针对上述问题,修复方案包含正确格式化URL、异常处理和反爬规避三个部分:

import pandas as pd
import requests
import time

df_list = []
for code in target_list_onlynumber:
    # 用f-string正确替换股票代码
    url = f'https://datacenter-web.eastmoney.com/api/data/v1/get?reportName=RPT_EXECUTIVE_HOLD_DETAILS&columns=ALL&filter=(SECURITY_CODE%3D"{code}")'
    
    try:
        # 添加请求头模拟浏览器,降低反爬概率
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
        }
        response = requests.get(url, headers=headers)
        response.raise_for_status()  # 检查请求是否成功(如404、500等)
        
        data_json = response.json()
        result = data_json.get('result')
        
        if result is not None:
            exec_data = result.get('data')
            if exec_data:  # 确保数据不为空
                df_i = pd.DataFrame(exec_data)
                df_list.append(df_i)
                print(f"成功获取股票{code}数据")
            else:
                print(f"股票{code}无高管持股数据")
        else:
            print(f"请求股票{code}返回无结果")
            
    except requests.exceptions.RequestException as e:
        print(f"请求股票{code}失败:{str(e)}")
    except ValueError:
        print(f"股票{code}的响应不是有效JSON")
    
    # 添加1秒延迟,避免频繁请求触发反爬
    time.sleep(1)

# 合并所有DataFrame
final_df = pd.concat(df_list, ignore_index=True)
print(final_df)

关键修复点说明

  • URL格式化:使用f-string确保股票代码被正确替换,替代原代码中无效的{i}占位符。
  • 异常处理:捕获请求异常、JSON解析异常,避免单个股票请求失败导致整个循环终止。
  • 反爬规避:添加User-Agent请求头模拟浏览器,每次请求后添加1秒延迟,降低被拦截概率。
  • 空值判断:逐层检查result和data是否存在,避免因无数据导致的AttributeError。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:50:09