如何解决下载SEC指定URL的JSON字典报403错误并提取数据到pandas?
解决403 Forbidden问题
SEC的EDGAR API对请求头校验非常严格,你使用的过时Firefox UA会被直接拦截,官方要求请求头的User-Agent字段需提供可识别的标识(比如你的姓名+邮箱组合),同时补充Accept头可进一步降低拦截概率。
可行的urllib实现方案
import urllib.request import json url = "https://data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json" # 替换为你自己的姓名+邮箱,符合SEC的请求要求 headers = { 'User-Agent': 'Your Name your.email@example.com', 'Accept': 'application/json' } request = urllib.request.Request(url, None, headers) with urllib.request.urlopen(request) as response: data = json.loads(response.read().decode('utf-8'))
更简洁的requests实现(推荐)
如果没安装requests先执行pip install requests
import requests import json url = "https://data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json" headers = { 'User-Agent': 'Your Name your.email@example.com', 'Accept': 'application/json' } response = requests.get(url, headers=headers) response.raise_for_status() data = response.json()
提取数据生成目标格式DataFrame
返回的JSON结构中,所有申报记录都在facts下的会计准则分类(通常是us-gaap)的字段明细中,你需要遍历所有明细的上报记录、去重后整理成目标格式:
import pandas as pd records = set() # 遍历所有us-gaap分类下的指标 for fact in data.get('facts', {}).get('us-gaap', {}).values(): # 遍历指标下的所有单位分类(通常是USD) for unit_list in fact.get('units', {}).values(): for entry in unit_list: # 只取包含所需字段的记录 if all(k in entry for k in ['filed', 'fp', 'form', 'accn']): # 用tuple存入set自动去重 records.add((entry['filed'], entry['fp'], entry['form'], entry['accn'])) # 转换为DataFrame df = pd.DataFrame(records, columns=['filed_date', 'filed_periode', 'form', 'accn']) # 按申报日期降序排序 df = df.sort_values('filed_date', ascending=False).reset_index(drop=True) print(df)
- 注意:SEC API请求频率限制为每秒最多10次,批量请求时需要添加间隔避免被临时封禁。
内容的提问来源于stack exchange,提问作者gunardilin
相关产品推荐
相关产品推荐

