如何使用美丽的汤来刮擦SEC的Edgar数据库并接收需求数据

时间:2019-04-11 00:04:16

标签: python beautifulsoup edgar

道歉是一个长期的问题-我是Python的新手,我正在尝试在相当特定的情况下尽可能地明确。

我正在尝试从SEC归档中常规识别特定数据点,但是我想实现这一点的自动化,而不必手动搜索公司的CIK ID和表单文件。到目前为止,我已经能够下载有关给定时间内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包可以查询我感兴趣的数据。我知道那里有一些有关Form 10-K和Form 10-Q的高级信息,但是我在Form中Ds有点晦涩。我只是想确保自己将时间有效地用于最佳解决方案。

谢谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您需要定义一个函数,该函数实质上可以是您发布的大多数代码,并且该函数应带有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

答案 1 :(得分:0)

假设在上面的列表中,您有一个数据框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)

然后从那里去。