Как использовать Beautiful Soup для очистки базы данных SEC Edgar и получения данных о желаниях - PullRequest
3 голосов
/ 11 апреля 2019

Заранее извиняюсь за длинный вопрос - я новичок в Python и пытаюсь быть как можно более откровенным в довольно конкретной ситуации.

Я пытаюсь идентифицировать конкретные точки данных из заявок SEC на регулярной основе, однако я хочу автоматизировать это, вместо того, чтобы вручную искать идентификатор CIK компании и заполнение форм.До сих пор я был в состоянии добраться до точки, где я загружаю метаданные обо всех регистрациях, полученных SEC за данный период времени.Это выглядит так:

index   cik         conm             type        date           path
0   0   1000045 NICHOLAS FINANCIAL INC  10-Q   2019-02-14   edgar/data/1000045/0001193125-19-039489.txt
1   1   1000045 NICHOLAS FINANCIAL INC  4   2019-01-15  edgar/data/1000045/0001357521-19-000001.txt
2   2   1000045 NICHOLAS FINANCIAL INC  4   2019-02-19  edgar/data/1000045/0001357521-19-000002.txt
3   3   1000045 NICHOLAS FINANCIAL INC  4   2019-03-15  edgar/data/1000045/0001357521-19-000003.txt
4   4   1000045 NICHOLAS FINANCIAL INC  8-K 2019-02-01  edgar/data/1000045/0001193125-19-024617.txt   

Несмотря на всю эту информацию, а также на возможность загрузки этих текстовых файлов и просмотра основных данных, я не могу проанализировать эти данные, так как они в формате xbrl инемного вне моей рубки.Вместо этого я наткнулся на этот сценарий (любезно предоставленный с этого сайта https://www.codeproject.com/Articles/1227765/Parsing-XBRL-with-Python):

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)    

. Просто запуск этого сценария работает именно так, как я хотел бы. Он возвращает акционерный капитал для данной компании (IBM вв этом случае), и я могу затем взять это значение и записать его в файл Excel.

Мой вопрос состоит из двух частей:

  1. Я взял три соответствующих столбца (CIK,тип и дату) из моей исходной таблицы метаданных, приведенной выше, и записал ее в список кортежей - я думаю, это так и называется - выглядит так [('1009759', 'D', '20190215'), ('1009891', 'D', '20190206'), ...]).Как мне взять эти данные, заменить начальную часть сценария, который я нашел, и выполнить цикл по нему, чтобы я мог получить список желаемых значений для каждой компании, подачи и даты?
  2. Существует ли вообщелучший способ сделать это?Я бы подумал, что будет какой-то пакет API или python для запроса данных, которые меня интересуют. Я знаю, что есть некоторая информация высокого уровня для форм 10-Ks и Form 10-Qs, однако я нахожусь в формеDs, который является немного неясным.Я просто хочу убедиться, что я трачу свое время эффективно на лучшее решение.

Спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 12 апреля 2019

Предполагая, что у вас есть фрейм данных sec с правильно названными столбцами для вашего списка заявок, вы должны сначала извлечь из фрейма данных соответствующую информацию в три списка:

cik = list(sec['cik'].values)
dat = list(sec['date'].values)
typ = list(sec['type'].values)

Затем вы создаете base_url со вставленными элементами и получаете ваши данные:

for c, t, d in zip(cik, typ, dat):
  base_url = f"https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&CIK={c}&type={t}&dateb={d}"
  edgar_resp = requests.get(base_url)

И иди оттуда.

0 голосов
/ 11 апреля 2019

Вам нужно определить функцию, которая может составлять большую часть кода, который вы опубликовали, и эта функция должна принимать 3 аргумента ключевого слова (ваши 3 значения). Тогда вместо того, чтобы определять три в вашем коде, вы просто передаете эти значения и возвращаете результат.

Затем вы берете свой список, который вы создали, и делаете вокруг него простой цикл for для вызова функции, которую вы определили с этими тремя значениями, а затем что-то делаете с результатом.

def get_data(value1, value2, value3):
    # your main code here but replace with your arguments above.
    return content

for company in companies:
    content = get_data(value1, value2, value3)
    # do something with content
...