使用 Python 3.9 通过 EDGAR 从 sec.gov 下载文件
Downloading files from sec.gov via EDGAR using Python 3.9
我是编码领域的新手,所以如果我误用术语或通常不知道我在说什么,请多多包涵。我正在做一个研究项目,我试图通过 EDGAR 从 sec.gov 中抓取 public 公司 10-Ks。我阅读了各种资源,观看了各种视频,但我发现以下参考与我的项目最相关,坦率地说,我很容易理解。我的代码的解释从第 194 页开始,代码从第 195 页开始。我首先尝试下载索引文件(下图),这将帮助我编写代码来专门获得 10-Ks。所以,我正处于项目的早期阶段。
这只是我正在使用的论文的参考。它目前在 SSRN 上,所以我意识到每个人都可能无法访问。我会上传 PDF,但我不认为这是一个选项。我列出这个纯粹是为了表明我有我正在做的事情的来源。如有需要,我可以提供截图。
Anand, V., Bochkay, K., Chychyla, R., & Leone, A. J. (2020)。在会计研究中使用 Python 进行文本分析。即将出版,会计基础和趋势。
索引文件示例:
目前,我有两个问题:我的代码没有按预期工作,我似乎被 sec.gov 阻止了。我将首先讨论前者,最后讨论后者。
当我在下面 运行 时,它应该在 down_direct 路径下载 2018 年和 2019 年的索引文件。但是,此代码仅抓取 2018 索引文件。
下面的log/IDLEshell结果显示了“成功”和不成功运行。不成功的运行让我觉得我被sec.gov屏蔽了。据我了解,某些网站会查找来自 urllib.request 的请求,并可能会自动对其进行筛选。然而,sec.gov 是研究人员友好的,只要你在下班后尝试下载 spaced 次尝试,这两种尝试我都做过(我昨晚从晚上 7 点到晚上 10 点一直在研究这个,并在两次尝试之间等待了 10 分钟左右).
所以,我的问题是
我应该如何调整我的代码以使其 运行 符合预期? (即,拉出 start_year 和 end_year 的所有 4 个季度)
我被sec.gov屏蔽了吗?如果是这样,我可以调整我的代码来解决这个问题吗?
import os
import urllib.request
from pathlib import Path
def get_index(start_year:int, end_year:int, down_direct:str):
start_year = 2018
end_year = 2019
down_direct = r"C:/Users/Documents/Student Files/~Current Student/~RESEARCH/~First Summer Paper/Data/EDGAR/"
print('Retrieving data')
if not os.path.exists(down_direct):
os.makedirs(down_direct)
for year in range(start_year, end_year+1):
for qtr in range(1,5):
url = r"https://www.sec.gov/Archives/edgar/full-index/" + str(year) + '/' + 'QTR' + str(qtr) + '/master.idx'
dl_file = down_direct + 'master' + str(year) + str(qtr) + '.idx'
urllib.request.urlretrieve(url, dl_file)
print('Downloaded', dl_file, end = '\n')
print('Data retrieved')
return
down_direct = os.path.join(Path.home(), 'edgar', 'indexfiles')
get_index(2018, 2019, down_direct)
成功运行
Retrieving Data
Downloaded C:/Users/Documents/Student Files/~Current
Student/~RESEARCH/~First Summer Paper/Data/EDGAR/master20184.idx
Data retrieved
不成功运行(为了space,我只包含错误行)
Retrieving Data
urllib.error.HTTPError: HTTP Error 403: Forbidden
我见过类似的 posts,人们建议将以下代码添加到代码中以解决此错误,但我太新手了,我真的不知道如何将其合并。感谢任何帮助,如果我需要用更多信息编辑我的 post,请告诉我。
req = Request(url, headers={'User-Agent': 'Mozilla/5.0'})
import requests
heads = {'Host': 'www.sec.gov', 'Connection': 'close',
'Accept': 'application/json, text/javascript, */*; q=0.01', 'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
}
def download(year):
for qtr in range(1, 5):
url = f"https://www.sec.gov/Archives/edgar/full-index/{year}/QTR{qtr}/master.idx"
response = requests.get(url, headers=heads)
print(url)
response.raise_for_status()
down_direct = r"C:/Users/Documents/Student Files/~Current Student/~RESEARCH/~First Summer Paper/Data/EDGAR/"
with open(f'{down_direct}/master{year}QTR{qtr}.idx', 'wb') as f:
f.write(response.content)
start_year =2018
end_year = 2019
for i in range(start_year,end_year+1):
download(i)
您不需要下载 .idx 索引文件。相反,您可以使用 SEC API 以编程方式查询所有 10-K 文件。
Python 示例
query
接受 Lucene 查询语法 (see 1 min tutorial here) 来构建过滤条件,例如return 2019 年至今提交的所有 10-K 文件。您可以按行业、部门、公司代码和 +20 个其他参数进行过滤。
from sec_api import QueryApi
queryApi = QueryApi(api_key="YOUR_API_KEY")
query = {
"query": { "query_string": {
"query": "formType:\"10-K\" AND filedAt:{2019-01-01 TO 2021-06-20}"
} },
"from": "0",
"size": "10",
"sort": [{ "filedAt": { "order": "desc" } }]
}
filings = queryApi.get_filings(query)
print(filings)
您可以使用 render API to get the entire 10-K filing (or exhibits, eg XBRL). Or you can use the item extraction API 从标准化明文或 HTML 文件中获取特定项目。
我是编码领域的新手,所以如果我误用术语或通常不知道我在说什么,请多多包涵。我正在做一个研究项目,我试图通过 EDGAR 从 sec.gov 中抓取 public 公司 10-Ks。我阅读了各种资源,观看了各种视频,但我发现以下参考与我的项目最相关,坦率地说,我很容易理解。我的代码的解释从第 194 页开始,代码从第 195 页开始。我首先尝试下载索引文件(下图),这将帮助我编写代码来专门获得 10-Ks。所以,我正处于项目的早期阶段。
这只是我正在使用的论文的参考。它目前在 SSRN 上,所以我意识到每个人都可能无法访问。我会上传 PDF,但我不认为这是一个选项。我列出这个纯粹是为了表明我有我正在做的事情的来源。如有需要,我可以提供截图。
Anand, V., Bochkay, K., Chychyla, R., & Leone, A. J. (2020)。在会计研究中使用 Python 进行文本分析。即将出版,会计基础和趋势。
索引文件示例:
目前,我有两个问题:我的代码没有按预期工作,我似乎被 sec.gov 阻止了。我将首先讨论前者,最后讨论后者。 当我在下面 运行 时,它应该在 down_direct 路径下载 2018 年和 2019 年的索引文件。但是,此代码仅抓取 2018 索引文件。
下面的log/IDLEshell结果显示了“成功”和不成功运行。不成功的运行让我觉得我被sec.gov屏蔽了。据我了解,某些网站会查找来自 urllib.request 的请求,并可能会自动对其进行筛选。然而,sec.gov 是研究人员友好的,只要你在下班后尝试下载 spaced 次尝试,这两种尝试我都做过(我昨晚从晚上 7 点到晚上 10 点一直在研究这个,并在两次尝试之间等待了 10 分钟左右). 所以,我的问题是
我应该如何调整我的代码以使其 运行 符合预期? (即,拉出 start_year 和 end_year 的所有 4 个季度)
我被sec.gov屏蔽了吗?如果是这样,我可以调整我的代码来解决这个问题吗?
import os import urllib.request from pathlib import Path def get_index(start_year:int, end_year:int, down_direct:str): start_year = 2018 end_year = 2019 down_direct = r"C:/Users/Documents/Student Files/~Current Student/~RESEARCH/~First Summer Paper/Data/EDGAR/" print('Retrieving data') if not os.path.exists(down_direct): os.makedirs(down_direct) for year in range(start_year, end_year+1): for qtr in range(1,5): url = r"https://www.sec.gov/Archives/edgar/full-index/" + str(year) + '/' + 'QTR' + str(qtr) + '/master.idx' dl_file = down_direct + 'master' + str(year) + str(qtr) + '.idx' urllib.request.urlretrieve(url, dl_file) print('Downloaded', dl_file, end = '\n') print('Data retrieved') return down_direct = os.path.join(Path.home(), 'edgar', 'indexfiles') get_index(2018, 2019, down_direct)
成功运行
Retrieving Data
Downloaded C:/Users/Documents/Student Files/~Current Student/~RESEARCH/~First Summer Paper/Data/EDGAR/master20184.idx
Data retrieved
不成功运行(为了space,我只包含错误行)
Retrieving Data
urllib.error.HTTPError: HTTP Error 403: Forbidden
我见过类似的 posts,人们建议将以下代码添加到代码中以解决此错误,但我太新手了,我真的不知道如何将其合并。感谢任何帮助,如果我需要用更多信息编辑我的 post,请告诉我。
req = Request(url, headers={'User-Agent': 'Mozilla/5.0'})
import requests
heads = {'Host': 'www.sec.gov', 'Connection': 'close',
'Accept': 'application/json, text/javascript, */*; q=0.01', 'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
}
def download(year):
for qtr in range(1, 5):
url = f"https://www.sec.gov/Archives/edgar/full-index/{year}/QTR{qtr}/master.idx"
response = requests.get(url, headers=heads)
print(url)
response.raise_for_status()
down_direct = r"C:/Users/Documents/Student Files/~Current Student/~RESEARCH/~First Summer Paper/Data/EDGAR/"
with open(f'{down_direct}/master{year}QTR{qtr}.idx', 'wb') as f:
f.write(response.content)
start_year =2018
end_year = 2019
for i in range(start_year,end_year+1):
download(i)
您不需要下载 .idx 索引文件。相反,您可以使用 SEC API 以编程方式查询所有 10-K 文件。
Python 示例
query
接受 Lucene 查询语法 (see 1 min tutorial here) 来构建过滤条件,例如return 2019 年至今提交的所有 10-K 文件。您可以按行业、部门、公司代码和 +20 个其他参数进行过滤。
from sec_api import QueryApi
queryApi = QueryApi(api_key="YOUR_API_KEY")
query = {
"query": { "query_string": {
"query": "formType:\"10-K\" AND filedAt:{2019-01-01 TO 2021-06-20}"
} },
"from": "0",
"size": "10",
"sort": [{ "filedAt": { "order": "desc" } }]
}
filings = queryApi.get_filings(query)
print(filings)
您可以使用 render API to get the entire 10-K filing (or exhibits, eg XBRL). Or you can use the item extraction API 从标准化明文或 HTML 文件中获取特定项目。