Source code for edgarapi.edgar
from lxml import html
import requests
BASE_URL = "https://www.sec.gov"
[docs]class Company:
"""
Used for downloading filings for a particular company.
"""
[docs] def __init__(self, name, cik):
self.name = name
self.cik = cik
[docs] def get_filings_url(self, filing_type="", prior_to="", ownership="include", no_of_entries=100):
url = "https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&CIK=" + self.cik + "&type=" + filing_type + \
"&dateb=" + prior_to + "&owner=" + ownership + "&count=" + str(no_of_entries)
return url
[docs] def get_all_filings(self, filing_type="", prior_to="", ownership="include", no_of_entries=100):
page = requests.get(self.get_filings_url(filing_type, prior_to, ownership, no_of_entries))
return html.fromstring(page.content)
[docs]class Edgar:
"""
Used for getting companies.
"""
[docs] def __init__(self):
all_companies_page = requests.get("https://www.sec.gov/Archives/edgar/cik-lookup-data.txt")
all_companies_content = all_companies_page.content.decode("latin1")
all_companies_array = all_companies_content.split("\n")
del all_companies_array[-1]
all_companies_array_rev = []
for i, item in enumerate(all_companies_array):
if item == "":
continue
item_arr = item.split(":")
all_companies_array[i] = (item_arr[0], item_arr[1])
all_companies_array_rev.append((item_arr[1], item_arr[0]))
self.all_companies_dict = dict(all_companies_array)
self.all_companies_dict_rev = dict(all_companies_array_rev)
[docs] def get_cik_by_company_name(self, name):
return self.all_companies_dict[name]
[docs] def get_company_name_by_cik(self, cik):
return self.all_companies_dict_rev[cik]
[docs] def find_company_name(self, words):
possibleCompanies = []
words = words.lower()
for company in self.all_companies_dict:
if all(word in company.lower() for word in words.split(" ")):
possibleCompanies.append(company)
return possibleCompanies
[docs]class Filing:
"""
Class which allows downloading of filing and contains filing metadata.
"""
main_xpath = '//*[@id="formDiv"]/div/table/tr[2]/td[3]/a'
[docs] def __init__(self, elem):
self.url = BASE_URL + elem.attrib["href"]
self.elem = _get_request_as_html_obj(self.url)
@property
def text_content(self):
return self._get_text_content_by_link_xpath(self.main_xpath)
@property
def content(self):
return self._get_html_by_link_xpath(self.main_xpath)
@property
def filing_date(self):
return self._get_filing_info('Filing Date')
@property
def accepted(self):
return self._get_filing_info('Accepted')
@property
def period_of_report(self):
return self._get_filing_info('Period of Report')
[docs] def sub_filing(self, sub_document, as_html = False):
xpath = '//*[@id="formDiv"]/div/table/tr[td[4]/text()="{sub_document}"]/td[3]/a'.format(
sub_document=sub_document
)
if as_html:
return self._get_html_by_link_xpath(xpath)
return self._get_text_content_by_link_xpath(xpath)
def _get_content_by_link_xpath(self, xpath):
url = BASE_URL + self.elem.xpath(xpath)[0].attrib["href"]
content = _get_request_as_html_obj(url)
return content
def _get_text_content_by_link_xpath(self, xpath):
content = self._get_content_by_link_xpath(xpath)
return content.body.text_content()
def _get_html_by_link_xpath(self, xpath):
content = self._get_content_by_link_xpath(xpath)
return html.tostring(content).decode('utf8')
def _get_filing_info(self, info_str):
info_xpath = '//*[@id="formDiv"]//div[@class="formGrouping"]/div[preceding-sibling::div[1]/' \
'text()="{info_str}"]/text()'.format(info_str=info_str)
return self.elem.xpath(info_xpath)[0]
def _get_request_as_html_obj(href):
page = requests.get(href)
return html.fromstring(page.content)
[docs]def get_documents(tree, sub_document=None, no_of_documents=1, as_html=False):
filings = get_filings(tree, no_of_documents=no_of_documents)
if sub_document is None:
if as_html:
attr = 'content'
else:
attr = 'text_content'
result = [getattr(filing, attr) for filing in filings]
else:
result = [filing.sub_filing(sub_document, as_html=as_html) for filing in filings]
if len(result) == 1:
return result[0]
return result
[docs]def get_filings(tree, no_of_documents=1):
elems = tree.xpath('//*[@id="documentsbutton"]')[:no_of_documents]
return [Filing(elem) for elem in elems]
def _get_sub_document_xpath(sub_document=None):
if sub_document is None:
return '//*[@id="formDiv"]/div/table/tr[2]/td[3]/a'
return '//*[@id="formDiv"]/div/table/tr[td[4]/text()="{sub_document}"]/td[3]/a'.format(sub_document=sub_document)
[docs]def get_cik_from_company(companyName):
tree = _get_request_as_html_obj("https://www.sec.gov/cgi-bin/browse-edgar?company=" + companyName)
CIKList = tree.xpath('//*[@id="seriesDiv"]/table/tr[*]/td[1]/a/text()')
namesList = []
for elem in tree.xpath('//*[@id="seriesDiv"]/table/tr[*]/td[2]'):
namesList.append(elem.text_content())
return list(zip(CIKList, namesList))