如何通过Python获取SEC EDGAR中MSFT 10-Q的自定义XBRL标签数据
问题:如何获取SEC文件中使用自定义标签的企业数据(以MSFT 10-Q为例)
我需要获取微软(MSFT)2023年9月30日10-Q文件中未使用US-GAAP标签的数据。
通常我可以通过US-GAAP标签键获取折旧摊销数据,代码如下:
dep_amort_data = companyFacts.json()['facts']['us-gaap'].get('DepreciationDepletionAndAmortization', {})

但微软这类企业会对特定数值使用自定义标签:
我尝试将代码中的us-gaap替换为小写的ticker(即msft),并更换对应标签名DepreciationAmortizationAndOther,但无法找到数据:
dep_amort_data = companyFacts.json()['facts']['msft'].get('DepreciationAmortizationAndOther', {})
我想知道该如何解决这个问题——从截图看数值确实存在,难道它没有存储在facts字段里?
附上我的完整方法(已移除邮箱):
def fetch_data_from_sec_edgar(cik, ticker): headers = { 'User-Agent': 'EMAIL', } # Get company facts data companyFacts = requests.get( f'https://data.sec.gov/api/xbrl/companyfacts/CIK{cik}.json', headers=headers ) # Check for successful response if companyFacts.status_code != 200: print("Failed to fetch company facts") return 0 # Try to fetch the depreciation and amortization data from the latest 10-Q try: if dep_amort_data: # Filter for 10-Q filings dep_amort_10q_data = [item for item in dep_amort_data.get('units', {}).get('USD', []) if item['form'] == '10-Q'] if dep_amort_10q_data: # Find the most recent entry most_recent_dep_amort = max(dep_amort_10q_data, key=lambda x: x['end'], default={}) return most_recent_dep_amort.get('val', 0) else: print("No 10-Q Depreciation and Amortization Data Found") return 0 else: tag_ticker = ticker.lower() dep_amort_data = companyFacts.json()['facts'][tag_ticker].get('DepreciationAmortizationAndOther', {}) if dep_amort_data: dep_amort_10q_data = [item for item in dep_amort_data.get('units', {}).get('USD', []) if item['form'] == '10-Q'] print(dep_amort_10q_data) if dep_amort_10q_data: # Find the most recent entry most_recent_dep_amort = max(dep_amort_10q_data, key=lambda x: x['end'], default={}) return most_recent_dep_amort.get('val', 0) else: print("No 10-Q Depreciation and Amortization Data Found") return 0 else: print("No Depreciation and Amortization Data Found") return 0 except KeyError as e: print(f"Error fetching depreciation and amortization data: {e}") return 0 if __name__ == "__main__": ticker = 'MSFT' cik = get_cik_from_ticker(ticker) dep_amort_value = fetch_data_from_sec_edgar(cik, ticker) print(dep_amort_value)
解决方案
1. 先确认自定义标签的命名空间
SEC的Company Facts API中,自定义标签的命名空间不是简单的ticker小写,而是企业注册的XBRL扩展命名空间的缩写。你可以先打印所有可用的命名空间,找到包含自定义标签的字段:
company_facts_json = companyFacts.json() print("Available namespaces:", list(company_facts_json['facts'].keys()))
运行后就能看到对应自定义标签的命名空间,再用该命名空间去查找目标标签。
2. 遍历所有命名空间查找目标标签
如果不确定命名空间,可以直接遍历facts下的所有命名空间,搜索目标标签名:
company_facts_json = companyFacts.json() target_tag = 'DepreciationAmortizationAndOther' for namespace in company_facts_json['facts']: if target_tag in company_facts_json['facts'][namespace]: dep_amort_data = company_facts_json['facts'][namespace][target_tag] # 过滤10-Q数据 dep_amort_10q_data = [item for item in dep_amort_data.get('units', {}).get('USD', []) if item['form'] == '10-Q'] if dep_amort_10q_data: most_recent_dep_amort = max(dep_amort_10q_data, key=lambda x: x['end'], default={}) return most_recent_dep_amort.get('val', 0)
这种方式不需要提前知道命名空间,直接定位到包含目标标签的字段。
3. 修正现有代码的逻辑错误
你当前代码中存在明显问题:try块开头的if dep_amort_data:这一行,dep_amort_data此时未定义,会直接触发NameError。以下是修正后的核心逻辑:
# 修正后的核心逻辑 company_facts_json = companyFacts.json() # 先尝试US-GAAP标签 dep_amort_data = company_facts_json['facts']['us-gaap'].get('DepreciationDepletionAndAmortization', {}) if dep_amort_data: dep_amort_10q_data = [item for item in dep_amort_data.get('units', {}).get('USD', []) if item['form'] == '10-Q'] if dep_amort_10q_data: most_recent_dep_amort = max(dep_amort_10q_data, key=lambda x: x['end'], default={}) return most_recent_dep_amort.get('val', 0) # US-GAAP找不到,遍历所有命名空间找自定义标签 target_tag = 'DepreciationAmortizationAndOther' for namespace in company_facts_json['facts']: if target_tag in company_facts_json['facts'][namespace]: dep_amort_data = company_facts_json['facts'][namespace][target_tag] dep_amort_10q_data = [item for item in dep_amort_data.get('units', {}).get('USD', []) if item['form'] == '10-Q'] if dep_amort_10q_data: most_recent_dep_amort = max(dep_amort_10q_data, key=lambda x: x['end'], default={}) return most_recent_dep_amort.get('val', 0) # 都找不到返回0 print("No Depreciation and Amortization Data Found") return 0
4. 备选方案:直接解析10-Q的XBRL实例文件
如果Company Facts API中确实没有该自定义标签的数据,你可以直接从10-Q的XBRL实例文件中提取:
- 通过SEC的Filings API获取对应10-Q的XBRL文件链接
- 下载并解析该XML格式的XBRL文件,查找自定义标签的值
这种方式复杂度稍高,但能确保获取到所有公开的标签数据。
内容的提问来源于stack exchange,提问作者mjebus
相关产品推荐
相关产品推荐

