Разбор контента с BeautifulSoup - PullRequest
0 голосов
/ 23 июня 2019

Я пытаюсь написать сценарий, который будет принимать CIK, тип отчета и, при желании, дату и возвращать информацию о разобранном финансовом отчете из открытого индекса SEC EDGAR.

Скрипт в основном работает и возвращает фрейм данных всех значений с описанием и ссылочным годом, проанализированным из атрибута contextref.К сожалению, в контексте contextref для разных тегов достаточно много вариаций, и поэтому мне интересно, есть ли более чистый способ извлечения этой информации, чем использование некоторой логики и регулярных выражений, как в настоящее время.Я проверил документацию по xbrl, и она ссылается на элемент 'period', но не вижу его, когда проверяю tag.attrs. Хотите знать, есть ли более простой способ извлечения этой информации, кроме какого-то вонючего регулярного выражения.

Рад предоставить примеры более проблемных значений contextref, если это полезно.

Соответствующая часть кода ниже:

import pandas as pd
from bs4 import BeautifulSoup
from requests import get

link = 'https://www.sec.gov/Archives/edgar/data/789019/000156459018019062/msft-20180630.xml'
r = get(link)
str = r.text

soup = BeautifulSoup(str, 'lxml')
tags = soup.find_all()
df = pd.DataFrame(columns=['field','period','value']) 

for tag in tags:
    if ('us-gaap:' in tag.name   # only want gaap-related tags 
            and tag.text.isdigit()): # only want values, no commentary
        #a = re.match("^C_"+ re.escape(cik) + "_[0-9]", tag['contextref'])     
            name = tag.name.split('gaap:')[1]
            cref = tag['contextref'][-8:-4]
            value = tag.text
            df = df.append({'field': name, 'period': cref, 'value': value}, ignore_index=True)

print(df)

1 Ответ

2 голосов
/ 23 июня 2019

Боюсь, что ваш подход в корне ошибочен.Значением атрибута contextRef является произвольный идентификатор, который ссылается на элемент контекста в другом месте документа.Хотя в рассматриваемом примере может содержаться год, эти идентификаторы могут быть любыми (например, c1, c2, c3 и т. Д.). Чтобы получить год, необходимо разыменовать контекст, определенный атрибутом contextRef,и посмотрите на элементы в элементе <period>, например,

<xbrli:context id="c1">
  <xbrli:entity>
       <xbrli:identifier scheme="http://www.example.com/1234">1234</xbrli:identifier>

  </xbrli:entity>
  <xbrli:period>
     <xbrli:startDate>2018-01-01</xbrli:startDate>
     <xbrli:endDate>2018-12-31</xbrli:endDate>
  </xbrli:period>
</xbrl:context>

Кроме того, часть us-gaap: имени элемента является префиксом пространства имен.Документы XML могут законно использовать другие префиксы для ссылки на то же пространство имен.Важным является пространство имен, к которому привязан префикс через объявление xmlns:us-gaap="...", обычно в корневом элементе.Вы должны использовать анализатор XML с учетом пространства имен.Я не думаю, что beautifulsoup должным образом учитывает пространство имен.

Я считаю, что система SEC ограничивает файловые системы использованием «рекомендуемых» префиксов пространства имен, так что вы можете сойти с рук при таком подходев документах SEC, но я настоятельно рекомендую использовать процессор XBRL, который позаботится о пространствах имен, разыменовании контекстов и многих других проблемах, связанных с использованием XBRL. Arelle - это процессор XBRL с открытым исходным кодом, но доступно множество других.

Использование процессора XBRL также предоставит вам доступ к информации, такой как читабельные метки из таксономии.

...