我目前已设法刮刮所有的文件,为一个特定的代码。“‘AAPL”和每一种类型的文件及其链接都在一个庞大的字典中呈现。我只想要那些‘类型’:‘10-k’的链接,并下载所有的文件作为HTML文件。已经尝试循环遍历字典并附加到列表中,但仍然得到所有类型。
from urllib.request import urlopen
import certifi
import json
response = urlopen("https://financialmodelingprep.com/api/v3/sec_filings/AMZN?page=0&apikey=aa478b6f376879bc58349bd2a6f9d5eb", cafile=certifi.where())
data = response.read().decode("utf-8")
print (json.loads(data))
list = []
for p_id in data:
if p_id['type'] == '10-K':
list.append((p_id['finalLink']))
print(list)
#print(get_jsonparsed_data(url))此代码的结果如下所示,当只需要10-k时,将输出每个类型:
{'symbol': 'AMZN', 'fillingDate': '2014-01-31 00:00:00', 'acceptedDate': '2014-01-30 21:52:38', 'cik': '0001018724', 'type': '10-K', 'link': 'https://www.sec.gov/Archives/edgar/data/1018724/000101872414000006/0001018724-14-000006-index.htm', 'finalLink': 'https://www.sec.gov/Archives/edgar/data/1018724/000101872414000006/amzn-20131231x10k.htm'}, {'symbol': 'AMZN', 'fillingDate': '2014-01-31 00:00:00', 'acceptedDate': '2014-01-30 21:49:36', 'cik': '0001018724', 'type': 'SC 13G/A', 'link': 'https://www.sec.gov/Archives/edgar/data/1018724/000119312514029210/0001193125-14-029210-index.htm', 'finalLink': 'https://www.sec.gov/Archives/edgar/data/1018724/000119312514029210/d659830dsc13ga.htm'}, {'symbol': 'AMZN', 'fillingDate': '2014-01-30 00:00:00', 'acceptedDate': '2014-01-30 16:20:30', 'cik': '0001018724', 'type': '8-K', 'link': 如果链接被附加到列表中,理想情况下,我希望立即下载所有链接并保存在文件夹中。以前使用过sec_edgar_downloader包,但是它会在各自的年度文件夹中下载所有的10k文件。
发布于 2022-10-28 19:28:05
与其在Python代码中过滤客户端所有SEC文件的列表,不如在服务器端直接过滤它们。考虑到你的最终目标是在很多年内下载成千上万的10-K文件,而不仅仅是苹果的10-K文件,你可以通过在服务器端进行过滤来节省大量的时间。
只有FYI,还有其他10-K变体,即10-KT,10 K,10 KT 405,10 K 40,10-K405.我不确定你是否意识到它们,并想忽略它们,或者你是否不知道,但也想下载其他变体。
让我们运行一个成熟的10-K文件下载程序的实现。我们的应用程序将分为两个组件:
1.生成10-K网址的列表
Query是一个搜索接口,允许我们通过任何文件元数据参数在整个EDGAR数据库中搜索和查找SEC文件。例如,我们可以使用滴答键和表单类型搜索(formType:"10-K" AND ticker:AAPL)找到苹果提交的所有10-K文件,或者使用布尔和括号运算符构建更复杂的搜索表达式。
query返回与搜索查询相匹配的SEC文件的元数据,包括URL到文件本身。
Query包的响应表示一个字典(简短: dict),其中包含两个键:total和filings。total的值本身就是一个小块,它告诉我们,除其他外,总共有多少文件与我们的搜索查询匹配。filings的值是一个dicts列表,其中每个dict表示匹配文件的所有元数据。
10-K文件的URL是每个归档数据集中linkToFilingDetails键的值,例如:https://www.sec.gov/Archives/edgar/data/1318605/000119312514069681/d668062d10k.htm
为了让我们生成一个完整的10-KURL列表,我们只需遍历所有归档数据集,读取linkToFilingDetails值并将该URL写入一个本地文件。
需要一些时间来下载和保存所有的URL。计划至少30分钟不间断地运行您的应用程序。
URL下载器在每次处理迭代时将一个新的URL附加到日志文件filing_urls.txt。如果您不小心关闭了应用程序,您可以从最近处理的一年开始,而不必再下载已经处理的URL。
如果您想一次生成所有URL,请取消代码中下面两行的注释。我故意取消注释,以提供整个代码的快速运行示例,而不必等待30+分钟才能看到结果。for year in range(2022, 2009, -1): for from_batch in range(0, 9800, 200):
from sec_api import QueryApi
queryApi = QueryApi(api_key="YOUR_API_KEY")
"""
On each search request, the PLACEHOLDER in the base_query is replaced
with our form type filter and with a date range filter.
"""
base_query = {
"query": {
"query_string": {
"query": "PLACEHOLDER", # this will be set during runtime
"time_zone": "America/New_York"
}
},
"from": "0",
"size": "200", # dont change this
# sort returned filings by the filedAt key/value
"sort": [{ "filedAt": { "order": "desc" } }]
}
# open the file we use to store the filing URLs
log_file = open("filing_urls.txt", "a")
# start with filings filed in 2022, then 2020, 2019, ... up to 2010
# uncomment next line to fetch all filings filed from 2022-2010
# for year in range(2022, 2009, -1):
for year in range(2022, 2020, -1):
print("Starting download for year {year}".format(year=year))
# a single search universe is represented as a month of the given year
for month in range(1, 13, 1):
# get 10-Q and 10-Q/A filings filed in year and month
# resulting query example: "formType:\"10-Q\" AND filedAt:[2021-01-01 TO 2021-01-31]"
universe_query = \
"formType:(\"10-K\", \"10-KT\", \"10KSB\", \"10KT405\", \"10KSB40\", \"10-K405\") AND " + \
"filedAt:[{year}-{month:02d}-01 TO {year}-{month:02d}-31]" \
.format(year=year, month=month)
# set new query universe for year-month combination
base_query["query"]["query_string"]["query"] = universe_query;
# paginate through results by increasing "from" parameter
# until we don't find any matches anymore
# uncomment next line to fetch all 10,000 filings
# for from_batch in range(0, 9800, 200):
for from_batch in range(0, 400, 200):
# set new "from" starting position of search
base_query["from"] = from_batch;
response = queryApi.get_filings(base_query)
# no more filings in search universe
if len(response["filings"]) == 0:
break;
# for each filing, only save the URL pointing to the filing itself
# and ignore all other data.
# the URL is set in the dict key "linkToFilingDetails"
urls_list = list(map(lambda x: x["linkToFilingDetails"], response["filings"]))
# transform list of URLs into one string by joining all list elements
# and add a new-line character between each element.
urls_string = "\n".join(urls_list) + "\n"
log_file.write(urls_string)
print("Filing URLs downloaded for {year}-{month:02d}".format(year=year, month=month))
log_file.close()
print("All URLs downloaded")运行代码之后,您应该会看到如下内容:

2.从证券交易委员会下载所有10-k
文件下载程序的第二个组件将日志文件filing_urls.txt中的所有10-KURL加载到内存中,并将20个文件并行下载到文件夹filings中。所有文件都下载到同一个文件夹中。
我们使用SEC-API Python包的呈现API接口通过提供其URL下载文件。呈现API允许我们并行下载多达40 SEC文件每秒。但是,我们没有利用API的全部带宽,因为否则很可能导致内存溢出异常(考虑到一些文件是400+ MB大的)。
download_filing函数从URL下载文件,使用URL的最后两个部分生成文件名,并将下载的文件保存到filings文件夹中。
download_all_filings是我们应用程序的核心和灵魂。在这里,Python内置的multiprocessing.Pool方法允许我们将一个函数并行地应用于一个值列表。通过这种方式,我们可以并行地将download_filing函数应用于URL列表的值。
例如,将number_of_processes设置为4将导致4个download_filing函数并行运行,其中每个函数处理一个URL。下载完成后,multiprocessing.Pool从URL列表中获取下一个URL,并使用新URL调用download_filing。
我们使用了40个URL (
urls = load_urls()[1:40])来快速测试代码,而不需要等待几个小时才能完成下载。取消注释处理所有URL的下一行:urls = load_urls()
import os
import multiprocessing
from sec_api import RenderApi
renderApi = RenderApi(api_key="YOUR_API_KEY")
# download filing and save to "filings" folder
def download_filing(url):
try:
filing = renderApi.get_filing(url)
# file_name example: 000156459019027952-msft-10k_20190630.htm
file_name = url.split("/")[-2] + "-" + url.split("/")[-1]
download_to = "./filings/" + file_name
with open(download_to, "w") as f:
f.write(filing)
except Exception as e:
print("Problem with {url}".format(url=url))
print(e)
# load URLs from log file
def load_urls():
log_file = open("filing_urls.txt", "r")
urls = log_file.read().split("\n") # convert long string of URLs into a list
log_file.close()
return urls
def download_all_filings():
print("Start downloading all filings")
download_folder = "./filings"
if not os.path.isdir(download_folder):
os.makedirs(download_folder)
# uncomment next line to process all URLs
# urls = load_urls()
urls = load_urls()[1:40]
print("{length} filing URLs loaded".format(length=len(urls)))
number_of_processes = 20
with multiprocessing.Pool(number_of_processes) as pool:
pool.map(download_filing, urls)
print("All filings downloaded")最后,运行download_all_filings()开始下载所有10-K文件。您的filings文件夹应该装满下载的10-K文件,如下所示:

https://stackoverflow.com/questions/74225258
复制相似问题