首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >努力构建BeautifulSoup,灵活抓取公司年度报告

努力构建BeautifulSoup,灵活抓取公司年度报告
EN

Stack Overflow用户
提问于 2020-03-15 03:15:36
回答 1查看 674关注 0票数 1

我试图使用美国证券和交易委员会(SEC)数据库,查看公司财务报告(称为10K),为每一份申报文件提取一份执行委员会成员名单。我目前正在使用微软(股票代码: MSFT)和沃尔玛(股票代码: WMT)的最新文件。我知道我可以在其他地方在金融网站上查找这些信息,但我正在努力建立一个灵活的数据库,供个人使用。我的问题是:

  1. 每个报告中的表索引位置是不同的,在一个公司报表上,我想要的表可能是表38,而在另一个公司报告上,可能是表45号,因此静态索引/职位计数不能在多个文件中工作。
  2. 每个HTML标记中的特定属性会发生变化,因此我无法搜索公共属性。在某些情况下,我找到了共同的属性,有时我找不到。

我开始认为,由于缺少每个文件中唯一的标识符,并且在所有文件中都是通用的,我可能无法自动完成这一任务。在过去的几周里,我一直在拼命地看Python、few抓取教程和视频。任何建议都很感激,完全自动化将是理想的,这样我就可以循环多个文件,部分帮助我在这里学习。我可能会遇到一些过于多样化的东西,试图实现自动化。

Microsoft:

https://www.sec.gov/Archives/edgar/data/789019/000156459019027952/msft-10k_20190630.htm

期望表:

代码语言:javascript
复制
<table border="0" cellspacing="0" cellpadding="0" align="center" style="border-collapse:collapse; width:100%;">

沃尔玛链接:

https://www.sec.gov/Archives/edgar/data/104169/000010416919000016/wmtform10-kx1312019.htm

期望表:

代码语言:javascript
复制
<table cellpadding="0" cellspacing="0" style="font-family:Times New Roman;font-size:10pt;width:100%;border-collapse:collapse;text-align:left;">

代码用于计数每页中的表数:

代码语言:javascript
复制
from selenium import webdriver
from bs4 import BeautifulSoup

chrome_path = r"C:\webdrivers\chromedriver.exe"
browser = webdriver.Chrome(chrome_path)

#Microsoft
browser.get("https://www.sec.gov/Archives/edgar/data/789019/000156459019027952/msft-10k_20190630.htm")
msft = browser.page_source
page_msft = BeautifulSoup(msft, 'html.parser')
tables_msft = page_msft.find_all("table")

#Walmart
browser.get("https://www.sec.gov/Archives/edgar/data/104169/000010416919000016/wmtform10-kx1312019.htm")
wmt = browser.page_source
page_wmt = BeautifulSoup(wmt, 'html.parser')
tables_wmt = page_wmt.find_all("table")

print("MSFT Result Table Count: " + str(len(tables_msft)))
print("Walmart Result Table Count: " + str(len(tables_wmt)))

结果:

MSFT结果表计数: 263

沃尔玛业绩表: 258

进程已完成,退出代码为0

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-16 06:57:38

首先,您不需要Selenium,请求库将更快并避免开销。因此,我能够找到一种方法来提取所需的数据。但由于列数不同,它们不能结合在一起(对于微软和沃尔玛)。下面的代码生成两个必需的数据,一个是微软的,一个是沃尔玛的。您仍然需要操作列名。因为它是唯一的表数据,所以我们的想法是将td值作为'Age‘的表。如果您需要澄清,请告诉我:

代码语言:javascript
复制
from bs4 import BeautifulSoup
import requests
import pandas as pd
import numpy as np


#Microsoft
page = requests.get("https://www.sec.gov/Archives/edgar/data/789019/000156459019027952/msft-10k_20190630.htm")
soup = BeautifulSoup(page.text, 'html')
resmsft = []
tables_msft = soup.find(text="Age").find_parent("table")
for row in tables_msft.find_all("tr")[1:]:
#    print([cell.get_text(strip=True) for cell in row.find_all("td")])
    if row:
        resmsft.append([cell.get_text(strip=True) for cell in row.find_all("td")])

non_empty = [sublist for sublist in resmsft if any(sublist)]
df_msft = pd.DataFrame.from_records(non_empty)
df_msft[df_msft==''] = np.nan 
df_msft=df_msft.dropna(axis=1,how='all')


#Walmart
page = requests.get("https://www.sec.gov/Archives/edgar/data/104169/000010416919000016/wmtform10-kx1312019.htm")
soup = BeautifulSoup(page.text, 'html')
#page_wmt = BeautifulSoup(soup, 'html.parser')
tables_wmt = soup.find(text="Age").find_parent("table")
reswmt = []
for row in tables_wmt.find_all("tr")[1:]:
#    print([cell.get_text(strip=True) for cell in row.find_all("td")])
    if row:
        reswmt.append([cell.get_text(strip=True) for cell in row.find_all("td")])
non_empty_wmt = [sublist for sublist in reswmt if any(sublist)]
df_wmt = pd.DataFrame.from_records(non_empty_wmt)
df_wmt[df_wmt==''] = np.nan 
df_wmt=df_wmt.dropna(axis=1,how='all')
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60689403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档