65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Python 解析 XBRL

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (9投票s)

2018年2月2日

CPOL

11分钟阅读

viewsIcon

74681

downloadIcon

624

使用 Python 从在线财务报告中提取数据。

我的上一篇文章解释了如何访问EDGAR数据库中的公司报告,但没有解释如何从报告中提取数据。如果你查看报告列表,你会发现 EDGAR 提供三种主要格式的报告:

  • 普通文本 - 以普通文件(*.txt)形式提供的数据
  • 网页 - 供浏览器查看的数据(*.htm
  • XBRL - 以 XBRL 格式文件(*.xml)形式提供的数据

如果你想自己阅读报告数据,前两个选项很好。但如果你想以编程方式提取数据,最后一个选项是最实用的。XBRL 文件对人类来说不容易阅读,但由于其结构,它们非常适合计算机。

本文介绍了 XBRL 格式,然后解释了如何使用 BeautifulSoup 读取 XBRL。最后,我将展示一个示例代码,它以编程方式从 EDGAR 下载并解析 XBRL 文件。

1. XBRL 简介

美国证券交易委员会 (SEC) 的主要职责是确保投资者拥有可靠的信息来做出决策。为此,SEC 要求上市公司提交准确反映其财务状况的报告。公司传统上以普通文本形式提供这些报告,但随着计算机化股票分析的普及,SEC 决定采用更结构化、计算机可读的格式。

SEC 选择了可扩展商业报告语言 (XBRL) 用于结构化公司报告。自 2009 年 4 月起,SEC 要求公司除了文本报告外,还以 XBRL 格式提供财务报告。此后,印度和英国也采用了 XBRL 进行公司报告。

XBRL 基于可扩展标记语言 (XML),但使用特殊的标签来标记财务数据。本节介绍了 XML 和命名空间的基础知识,然后概述了 XBRL。

1.1 XML、Schema 和命名空间

介绍 XML 的好方法是将其与 HTML 进行比较。HTML 文档使用嵌套标签来构造其内容,形式为 <xyz>...</xyz>。例如,HTML 使用 <b>...</b> 标签以粗体显示文本,例如 <b>Hi there!</b>。HTML 允许你通过属性控制标签的行为,例如 <p id="...">...</p> 中的 id 属性。

我喜欢将 XML 视为通用 HTML。XML 文档包含与 HTML 中的标签和属性相似的标签和属性,但 XML 不定义任何特定的标签或属性。相反,实现者可以通过创建模式(schema)来定义自己的标签和属性。模式在用 XML Schema Definition (XSD) 格式化的特殊 XML 文档中定义,因此,模式文档的后缀是 *.xsd 而不是 *.xml

XML 文档可以使用命名空间声明访问模式的标签和属性。例如,以下声明指定 XML 文档将访问位于 http://www.example.com 的模式中定义的标签和属性

xmlns:ex="http://www.example.com"

xmlns 部分代表 XML 命名空间,并且必须存在于每个命名空间声明中。ex 是可选的,用作从模式中获取的标签的前缀。例如,如果模式定义了一个名为 apple 的元素,XML 文档可以使用 <ex:apple>...</ex:apple> 标签访问该元素。

1.2 XBRL 报告和模式

XBRL 文档是一个 XML 文档,它使用 XBRL 的标签和属性来构造其内容。这听起来很简单,但单个文档可能需要访问来自许多不同模式的功能。例如,不同国家有不同的报告要求,因此美国报告将访问与英国报告不同的元素集。同样,不同类型的报告将需要不同的模式,因此年度报告将使用与招股说明书不同的标签。

对美国公司年度报告中标签/属性的详细讨论将占据一本厚厚的书。在本次讨论中,我的目标是介绍美国报告中常用的一些命名空间:

  1. 基本 XBRL 模式 - 提供 XBRL 文档的整体结构
  2. 美国文档和实体信息 (DEI) - 设置文档的类型和特征
  3. 美国公认会计原则 (GAAP) - 定义美国报告的必要元素
  4. 实体特定模式 - 定义报告提供实体特有的元素

你不需要记住这些命名空间的元素,但你越熟悉,就越能更好地从 XBRL 文档中提取数据。

1.2.1 基本 XBRL 模式

XBRL 的基本标签和属性在位于 http://www.xbrl.org/2003/instance 的模式中提供。文档通常通过 xbrli 前缀访问这些元素,如下面的命名空间声明所示:

xlmns:xbrli="http://www.xbrl.org/2003/instance"

在该模式定义的众多元素中,xbrli:xbrl 尤其重要。这是因为每个 XBRL 文档的内容都必须包含在 <xbrli:xbrl>...</xbrli:xbrl> 标签内。

要理解基本模式提供的其他标签,你应该熟悉以下术语:

  • instance - 根元素为 <xbrli:xbrl> 的 XBRL 文档
  • fact - 报告中的单个细节,例如 2000 万美元
  • concept - 与事实相关的含义,例如销售成本
  • entity - 概念所描述的公司或个人
  • context - 将实体与概念关联的数据结构

许多 XBRL 文档首先定义一个很长的上下文列表。每个上下文由一个 <xbrli:context> 元素表示,并且每个上下文都有一个 id 属性。每个 <xbrli:context> 元素都包含一个识别实体的 <xbrli:entity> 子元素。以下标记定义了一个 ID 为 FD2013Q4YTD 的上下文:

<xbrli:context id="FD2013Q4YTD">
    <xbrli:entity>
    <xbrli:identifier scheme="http://www.sec.gov/CIK">0001065088</xbrli:identifier>
  </xbrli:entity>
  <xbrli:period>
    <xbrli:startDate>2013-01-01</xbrli:startDate>
    <xbrli:endDate>2013-12-31</xbrli:endDate>
  </xbrli:period>
</xbrli:context>

文档后面的部分可以通过将 contextRef 属性分配给上下文的 ID 来引用此上下文。这在以下标记中显示:

<us-gaap:IncomeTaxDisclosureTextBlock contextRef="FD2013Q4YTD" ...>

1.2.2 美国文档和实体信息 (DEI)

提交给 SEC 的每个 XBRL 文档都需要提供有关其内容的信息。提交者可以通过包含美国文档和实体信息 (DEI) 模式中的元素来满足此要求。这些元素通常以 dei 为前缀,文档可以通过以下声明访问它们:

xlmns:dei="http://xbrl.sec.gov/dei/2014-01-31"

此模式中定义的元素标识 XBRL 报告的类型,并提供有关提交报告的实体的信息。表 1 列出了可用元素中的十一个。

表 1:美国文档和实体信息模式提供的元素(节选)
DocumentType 报告文档的类型
EntityCentralIndexKey 提交报告实体的 CIK
TradingSymbol 提交报告实体的交易代码
EntityCurrentReportingStatus 识别实体是否受备案要求约束
EntityFilerCategory 识别实体的备案类别(大型、小型等)
EntityRegistrantName 章程中给出的实体确切名称
DocumentFiscalPeriodFocus 文档关注的会计期间
DocumentFiscalYearFocus 文档关注的会计年度
CurrentFiscalYearEndDate 当前会计年度结束日期
AmendmentFlag 识别文档是否为已备案文档的修正案
previously-filed document
AmendmentDescription 修订文档中更改的描述

区分 EntityCentralIndexKeyTradingSymbolEntityRegistrantName 很重要。EntityCentralIndexKey 元素标识提交者的 CIK 代码,TradingSymbol 标识提交者的交易(股票代码)符号,EntityRegistrantName 提供实体的正式名称。

以下标记取自 eBay 年度报告,演示了 DEI 元素的使用方式:

<dei:DocumentType contextRef="..." id="Fact-...">
  10-K
</dei:DocumentType>
<dei:EntityCentralIndexKey contextRef="..." id="Fact-...">
  0001065088
</dei:EntityCentralIndexKey>
<dei:TradingSymbol contextRef="..." id="Fact-...">
  EBAY
</dei:TradingSymbol>
<dei:EntityRegistrantName contextRef="..." id="Fact-...">
  EBAY INC
</dei:EntityRegistrantName>
<dei:EntityFilerCategory contextRef="..." id="Fact-...">
  Large Accelerated Filer
</dei:EntityFilerCategory>

如所示,每个 DEI 元素都有一个 id 属性和一个 contextRef,它引用文档前面定义的 <xbrli:context> 元素。

1.2.3 美国公认会计原则 (GAAP)

为了确保企业在其会计报告中使用通用术语,美国财务会计准则委员会 (FASB) 提供了一套称为公认会计原则 (GAAP) 的标准。实体可以通过访问 FASB 的模式定义在其 XBRL 报告中提供 GAAP 数据。GAAP 元素通常以 us-gaap 前缀开头:

xmlns:us-gaap="http://fasb.org/us-gaap/2014-01-31" 

此模式提供了数千个与会计相关的元素,表 2 列出了其中一小部分但很重要的子集。你可以在此处查看更完整的表格。

表 2:美国公认会计原则模式的元素(节选)
AccountsPayableCurrent 截至资产负债表日应付供应商的负债
AccountsReceivableGross 应收客户或客户的款项
AccountsReceivableNet 应收客户或客户的款项,扣除
预计可变现价值
AccruedIncomeTaxes 已知和估计税收义务的未付总额
AccruedInsuranceCurrent 应付保险实体的赔付义务
AssetManagementCosts 与资产管理相关的总成本
AssetsCurrent 预计在一年内变现的所有资产的总和
BorrowedFunds 所有债务金额的总和
Cash 可用于运营需求的无限制现金
CommercialPaper 使用银行和公司发行的无担保
短期借款的价值
CommonStockNoParValue 无面值股票的每股发行价值
CommonStockSharesIssued 已出售或授予股东的普通股总数
sold or granted to shareholders
CommonStockValue 已发行普通股的总面值或声明价值
SalariesAndWages 除高级职员外的工资支出
ConvertibleDebt 可以转换为另一种形式的金融工具的债务金额,
例如普通股
CostOfGoodsSold 本期销售商品相关的总成本
CostOfServices 本期提供服务相关的总成本
CostsAndExpenses 本期销售成本和运营费用的总和
DebtCurrent 短期债务和长期债务到期日的总和
DeferredRevenue 尚未实现现金或其他资产
Depreciation 与有形资产成本相关的费用金额,在资产的
有用年限内
DirectOperatingCosts 与运营直接相关的总费用
Dividends 本期所有证券的现金、股票和已宣告股息的股权影响
for all securities during the period
EarningsPerShareBasic 本期每股普通股净收益(损失)
GrossProfit 总收入减去商品/服务销售成本和运营费用
operating expenses
IntangibleAssetsCurrent 非实物资产的流动部分,不包括金融资产
资源文件
InterestAndDebtExpense 与利息和债务支付相关的费用
InventoryGross 为未来销售或用于制造或生产而持有的商品、货物或用品
int manufacturing or production
Land 为生产性使用而持有的房地产,非为出售而持有
负债 所有已确认负债的总和
LiabilitiesAndStockholdersEquity 负债和股东权益的总和,包括归属于非控股权益的
部分权益
NetIncomeLoss 本期利润或损失的一部分,扣除所得税后
ProfitLoss 本期合并利润或损失
NotesPayable 应付票据的总金额,初始到期日超过一年或正常营业周期
beyond one year or the normal operating cycle
OfficersCompensation 高级职员的工资支出
OperatingCycle 实体营业周期(如果小于 12 个月)
OperatingExpenses 与正常运营相关的经常性成本,销售成本或服务成本中
不包含的费用
PreferredStockValue 已发行不可赎回优先股的声明价值
ResearchAndDevelopment
费用
在研发活动中发生的成本
activities
Revenues 本期确认的总收入
SharesIssued 已发行股票数量
SharesOutstanding 已发行和流通股数量
StockholdersEquity 股东权益项目总和,扣除应收高级职员、董事、
所有者和关联方的款项

你可以通过搜索相应的 us-gaap 元素来查找报告中的会计数据。例如,eBay 的 2014 年年度报告使用以下标记识别其总负债:

<us-gaap:Liabilities contextRef="..." decimals="..." id="..." unitRef="usd">
  25226000000
</us-gaap:Liabilities>

us-gaap 模式中有很多元素在名称和目的上非常相似。如果你正在搜索特定的会计数据,请务必不要混淆这些元素。

2. 使用 BeautifulSoup 解析 XBRL

下载 XBRL 文档后,你可以使用多种方法提取其数据。如果你知道你感兴趣的元素,你可以对文本执行暴力搜索,例如 us-gaap:Assets。另一方面,python-xbrl 库是专门为解析 XBRL 文档而创建的,但我从未让它正常工作。

本节解释了如何使用上一篇文章中介绍的 BeautifulSoup 包来解析 XBRL。你不需要学习任何新的类或方法,但重要的是要指定你要执行 XML 解析。如果你安装了 lxml 库 (pip install lxml),那么你可以使用以下代码创建 BeautifulSoup 实例:

soup = BeautifulSoup(..., 'lxml')

由于某种原因,当我调用 find_all 方法搜索 XBRL 标签时,返回的列表总是空的。但是当我无参数调用 find_all 时,返回的列表包含表示 XBRL 标签的 Tag。因此,我使用如下代码:

soup = BeautifulSoup(xbrl_string, 'lxml')
tag_list = soup.find_all()
for tag in tag_list:
    if tag.name == 'us-gaap:liabilities':
        print('Liabilities: ' + tag.text)

年度报告可能包含多个 <us-gaap:liabilities> 元素,每个元素对应一个不同的报告期。每个报告期对应一个 <context> 元素,因此你可以通过检查它们的 contextRef 属性来区分 GAAP 元素。

3. 完整的 EDGAR-XBRL 示例

如果你阅读了上一篇文章和本文的内容,你理解如何访问公司的 EDGAR 报告并在 Python 中解析它们应该没有任何问题。为了演示这一点,清单 1 中的代码在 EDGAR 中搜索 IBM(CIK: 0000051143)的 2014 年年度报告 (10-K),然后解析 XBRL 以确定股东权益 (us-gaap:stockholdersequity),

清单 1:从 IBM 年度报告中读取股东权益 (xbrl_reader.py)
from bs4 import BeautifulSoup
import requests
import sys

# Access page
cik = '0000051143'
type = '10-K'
dateb = '20160101'

# Obtain HTML for search page
base_url = "https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&CIK={}&type={}&dateb={}"
edgar_resp = requests.get(base_url.format(cik, type, dateb))
edgar_str = edgar_resp.text

# Find the document link
doc_link = ''
soup = BeautifulSoup(edgar_str, 'html.parser')
table_tag = soup.find('table', class_='tableFile2')
rows = table_tag.find_all('tr')
for row in rows:
    cells = row.find_all('td')
    if len(cells) > 3:
        if '2015' in cells[3].text:
            doc_link = 'https://www.sec.gov' + cells[1].a['href']

# Exit if document link couldn't be found
if doc_link == '':
    print("Couldn't find the document link")
    sys.exit()

# Obtain HTML for document page
doc_resp = requests.get(doc_link)
doc_str = doc_resp.text

# Find the XBRL link
xbrl_link = ''
soup = BeautifulSoup(doc_str, 'html.parser')
table_tag = soup.find('table', class_='tableFile', summary='Data Files')
rows = table_tag.find_all('tr')
for row in rows:
    cells = row.find_all('td')
    if len(cells) > 3:
        if 'INS' in cells[3].text:
            xbrl_link = 'https://www.sec.gov' + cells[2].a['href']

# Obtain XBRL text from document
xbrl_resp = requests.get(xbrl_link)
xbrl_str = xbrl_resp.text

# Find and print stockholder's equity
soup = BeautifulSoup(xbrl_str, 'lxml')
tag_list = soup.find_all()
for tag in tag_list:
    if tag.name == 'us-gaap:stockholdersequity':
        print("Stockholder's equity: " + tag.text)

此代码仅在 SEC 不更改 EDGAR 网站的标记时才能正常工作。当然,标记不太可能随时间保持不变,因此请记住,你可能需要深入研究标记以更新代码。

历史

  • 2018 年 2 月 2 日 - 文章首次提交
© . All rights reserved.