通过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')。
报错原因分析
- 字符串格式化错误:原代码用单引号包裹URL,其中的
{i}不会被Python解析为变量,请求的URL实际把"{i}"作为股票代码传给服务器,服务器返回无结果响应,导致result为None。 - 反爬机制触发:批量请求频率过高,网站服务器拒绝返回正常数据,响应不是预期JSON格式,解析后无
result字段。 - 部分股票无数据:部分股票可能没有高管持股记录,接口返回的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
相关产品推荐
相关产品推荐

