如何循环不同Series ID从FRED API自动下载数据?报错求助
问题描述
第一次用Python完成大学作业,需下载全美所有县的全交易房价指数。已从其他文件获取各区县FIPS编码,通过编码生成Series ID后,用API密钥循环获取对应数据,但大量编码返回错误:Error fetching data for county_id ATNHPIUS01095A: Expecting value: line 1 column 1 (char 0)
原始代码
import pandas as pd import requests df = pd.read_stata(r"D:\Entertaintment\Uni\Seminar Behavioural Finance\Group Assignment\unemployment 12-17.dta") df = df[['FIPS']] df['county_id'] = 'ATNHPIUS' + df['FIPS'].astype(str) + 'A' county_ids = df['county_id'].unique() print (df.head()) def fetch_data(county_id): api_key = "mykey" url = f'https://api.stlouisfed.org/fred/series/observations?series_id={county_id}&api_key={api_key}' try: response = requests.get(url) response.raise_for_status() data = response.json() observations = data['observations'] df = pd.DataFrame(observations) df['date'] = pd.to_datetime(df['date']) df.set_index('date', inplace=True) df.rename(columns={'value': county_id}, inplace=True) return df else: print(f"No observations found for county_id {county_id}") return None except requests.exceptions.RequestException as e: print(f"Error fetching data for county_id {county_id}: {e}") return None # Return None if data fetching fails for a county_id dataframes = [] for county_id in county_ids: data_df = fetch_data(county_ids) if data_df is not None: dataframes.append(data_df) combined_df = pd.concat(dataframes, axis=1) print(combined_df.head())
问题排查与修复方案
1. 循环传参错误
循环中调用fetch_data(county_ids)时,传入的是整个county_ids数组而非单个county_id,导致请求的series_id是数组字符串,必然返回无效响应。
修复:将循环内的调用改为fetch_data(county_id)。
2. try-except语法错误
代码中else块直接跟在try之后,语法非法。else需配合if判断使用,用来检查是否存在观测数据。
修复:在解析data['observations']后添加判断,若为空则返回提示。
3. API响应格式缺失
FRED API默认返回XML格式,直接调用response.json()会因解析失败抛出错误。需显式指定返回JSON格式。
修复:在请求URL中添加&file_type=json参数。
4. FIPS编码格式问题
部分FIPS编码是5位数字,转换为字符串时可能丢失前导零(如01095变为1095),导致生成的Series ID无效。
修复:使用str.zfill(5)确保FIPS编码为5位带前导零的字符串。
修复后的完整代码
import pandas as pd import requests # 读取FIPS数据并生成正确的county_id df = pd.read_stata(r"D:\Entertaintment\Uni\Seminar Behavioural Finance\Group Assignment\unemployment 12-17.dta") df = df[['FIPS']] # 确保FIPS是5位带前导零的字符串 df['county_id'] = 'ATNHPIUS' + df['FIPS'].astype(str).str.zfill(5) + 'A' county_ids = df['county_id'].unique() print(df.head()) def fetch_data(county_id): api_key = "mykey" # 添加file_type=json指定返回JSON格式 url = f'https://api.stlouisfed.org/fred/series/observations?series_id={county_id}&api_key={api_key}&file_type=json' try: response = requests.get(url) response.raise_for_status() # 触发HTTP错误异常 data = response.json() observations = data['observations'] # 判断是否有观测数据 if not observations: print(f"No observations found for county_id {county_id}") return None df = pd.DataFrame(observations) df['date'] = pd.to_datetime(df['date']) df.set_index('date', inplace=True) df.rename(columns={'value': county_id}, inplace=True) return df except requests.exceptions.RequestException as e: print(f"Error fetching data for county_id {county_id}: {e}") return None dataframes = [] # 循环传入单个county_id for county_id in county_ids: data_df = fetch_data(county_id) if data_df is not None: dataframes.append(data_df) combined_df = pd.concat(dataframes, axis=1) print(combined_df.head())
内容的提问来源于stack exchange,提问作者user24034607
相关产品推荐
相关产品推荐

