使用 Python 抓取 Yahoo Finance 损益表
Scrape Yahoo Finance Income Statement with Python
我正在尝试从 Yahoo Finance using Python. Specifically, let's say I want the most recent figure of Net Income of Apple 的损益表中抓取数据。
数据结构在一堆嵌套的 HTML-table 中。我正在使用 requests
模块访问它并检索 HTML.
我正在使用 BeautifulSoup 4 来筛选 HTML 结构,但我不知道如何得到这个数字。
Here是用Firefox分析的截图
到目前为止我的代码:
from bs4 import BeautifulSoup
import requests
myurl = "https://finance.yahoo.com/q/is?s=AAPL&annual"
html = requests.get(myurl).content
soup = BeautifulSoup(html)
我试过使用
all_strong = soup.find_all("strong")
然后得到第17个元素,正好是我要的那个图形,但是这样看起来很不优雅。像这样:
all_strong[16].parent.next_sibling
...
当然,目标是使用BeautifulSoup
搜索我需要的图形的名称(在本例中为"Net Income"),然后在 HTML-table.
的同一行中抓取 数字本身
如果有任何关于如何解决此问题的想法,我将不胜感激,请记住,我想应用该解决方案从其他 Yahoo Finance 页面检索大量其他数据。
解决方案/扩展:
下面@wilbur 的解决方案有效,我对其进行了扩展,以便能够获得 any 数字的值 any any 上市公司的财务页面(即 Income Statement, Balance Sheet, and Cash Flow Statement)。
我的函数如下:
def periodic_figure_values(soup, yahoo_figure):
values = []
pattern = re.compile(yahoo_figure)
title = soup.find("strong", text=pattern) # works for the figures printed in bold
if title:
row = title.parent.parent
else:
title = soup.find("td", text=pattern) # works for any other available figure
if title:
row = title.parent
else:
sys.exit("Invalid figure '" + yahoo_figure + "' passed.")
cells = row.find_all("td")[1:] # exclude the <td> with figure name
for cell in cells:
if cell.text.strip() != yahoo_figure: # needed because some figures are indented
str_value = cell.text.strip().replace(",", "").replace("(", "-").replace(")", "")
if str_value == "-":
str_value = 0
value = int(str_value) * 1000
values.append(value)
return values
yahoo_figure
变量是一个字符串。显然,这必须与雅虎财经上使用的人物名称完全相同。
要传递 soup
变量,我首先使用以下函数:
def financials_soup(ticker_symbol, statement="is", quarterly=False):
if statement == "is" or statement == "bs" or statement == "cf":
url = "https://finance.yahoo.com/q/" + statement + "?s=" + ticker_symbol
if not quarterly:
url += "&annual"
return BeautifulSoup(requests.get(url).text, "html.parser")
return sys.exit("Invalid financial statement code '" + statement + "' passed.")
示例用法 -- 我想从最近可用的损益表中获取 Apple Inc. 的所得税费用:
print(periodic_figure_values(financials_soup("AAPL", "is"), "Income Tax Expense"))
输出:[19121000000, 13973000000, 13118000000]
您还可以从 soup
中获取 期末 的日期,并创建一个字典,其中日期是键,数字是值, 但这会使 post 太长。
到目前为止,这似乎对我有用,但我总是感谢建设性的批评。
这变得有点困难,因为 "Net Income" 包含在 <strong>
标签中,请耐心等待,但我认为这可行:
import re, requests
from bs4 import BeautifulSoup
url = 'https://finance.yahoo.com/q/is?s=AAPL&annual'
r = requests.get(url)
soup = BeautifulSoup(r.text, 'html.parser')
pattern = re.compile('Net Income')
title = soup.find('strong', text=pattern)
row = title.parent.parent # yes, yes, I know it's not the prettiest
cells = row.find_all('td')[1:] #exclude the <td> with 'Net Income'
values = [ c.text.strip() for c in cells ]
values
,在这种情况下,将包含 "Net Income" 行中的三个 table 单元格(而且,我可能会补充说,可以很容易地转换为整数 - 我只是喜欢他们将“,”保留为字符串)
In [10]: values
Out[10]: [u'53,394,000', u'39,510,000', u'37,037,000']
当我在 Alphabet (GOOG) 上测试它时 - 它不起作用,因为我认为它们没有显示损益表 (https://finance.yahoo.com/q/is?s=GOOG&annual) but when I checked Facebook (FB), the values were returned correctly (https://finance.yahoo.com/q/is?s=FB&annual)。
如果您想创建一个更动态的脚本,您可以使用字符串格式将 url 格式化为您想要的任何股票代码,如下所示:
ticker_symbol = 'AAPL' # or 'FB' or any other ticker symbol
url = 'https://finance.yahoo.com/q/is?s={}&annual'.format(ticker_symbol))
我正在尝试从 Yahoo Finance using Python. Specifically, let's say I want the most recent figure of Net Income of Apple 的损益表中抓取数据。
数据结构在一堆嵌套的 HTML-table 中。我正在使用 requests
模块访问它并检索 HTML.
我正在使用 BeautifulSoup 4 来筛选 HTML 结构,但我不知道如何得到这个数字。
Here是用Firefox分析的截图
到目前为止我的代码:
from bs4 import BeautifulSoup
import requests
myurl = "https://finance.yahoo.com/q/is?s=AAPL&annual"
html = requests.get(myurl).content
soup = BeautifulSoup(html)
我试过使用
all_strong = soup.find_all("strong")
然后得到第17个元素,正好是我要的那个图形,但是这样看起来很不优雅。像这样:
all_strong[16].parent.next_sibling
...
当然,目标是使用BeautifulSoup
搜索我需要的图形的名称(在本例中为"Net Income"),然后在 HTML-table.
如果有任何关于如何解决此问题的想法,我将不胜感激,请记住,我想应用该解决方案从其他 Yahoo Finance 页面检索大量其他数据。
解决方案/扩展:
下面@wilbur 的解决方案有效,我对其进行了扩展,以便能够获得 any 数字的值 any any 上市公司的财务页面(即 Income Statement, Balance Sheet, and Cash Flow Statement)。 我的函数如下:
def periodic_figure_values(soup, yahoo_figure):
values = []
pattern = re.compile(yahoo_figure)
title = soup.find("strong", text=pattern) # works for the figures printed in bold
if title:
row = title.parent.parent
else:
title = soup.find("td", text=pattern) # works for any other available figure
if title:
row = title.parent
else:
sys.exit("Invalid figure '" + yahoo_figure + "' passed.")
cells = row.find_all("td")[1:] # exclude the <td> with figure name
for cell in cells:
if cell.text.strip() != yahoo_figure: # needed because some figures are indented
str_value = cell.text.strip().replace(",", "").replace("(", "-").replace(")", "")
if str_value == "-":
str_value = 0
value = int(str_value) * 1000
values.append(value)
return values
yahoo_figure
变量是一个字符串。显然,这必须与雅虎财经上使用的人物名称完全相同。
要传递 soup
变量,我首先使用以下函数:
def financials_soup(ticker_symbol, statement="is", quarterly=False):
if statement == "is" or statement == "bs" or statement == "cf":
url = "https://finance.yahoo.com/q/" + statement + "?s=" + ticker_symbol
if not quarterly:
url += "&annual"
return BeautifulSoup(requests.get(url).text, "html.parser")
return sys.exit("Invalid financial statement code '" + statement + "' passed.")
示例用法 -- 我想从最近可用的损益表中获取 Apple Inc. 的所得税费用:
print(periodic_figure_values(financials_soup("AAPL", "is"), "Income Tax Expense"))
输出:[19121000000, 13973000000, 13118000000]
您还可以从 soup
中获取 期末 的日期,并创建一个字典,其中日期是键,数字是值, 但这会使 post 太长。
到目前为止,这似乎对我有用,但我总是感谢建设性的批评。
这变得有点困难,因为 "Net Income" 包含在 <strong>
标签中,请耐心等待,但我认为这可行:
import re, requests
from bs4 import BeautifulSoup
url = 'https://finance.yahoo.com/q/is?s=AAPL&annual'
r = requests.get(url)
soup = BeautifulSoup(r.text, 'html.parser')
pattern = re.compile('Net Income')
title = soup.find('strong', text=pattern)
row = title.parent.parent # yes, yes, I know it's not the prettiest
cells = row.find_all('td')[1:] #exclude the <td> with 'Net Income'
values = [ c.text.strip() for c in cells ]
values
,在这种情况下,将包含 "Net Income" 行中的三个 table 单元格(而且,我可能会补充说,可以很容易地转换为整数 - 我只是喜欢他们将“,”保留为字符串)
In [10]: values
Out[10]: [u'53,394,000', u'39,510,000', u'37,037,000']
当我在 Alphabet (GOOG) 上测试它时 - 它不起作用,因为我认为它们没有显示损益表 (https://finance.yahoo.com/q/is?s=GOOG&annual) but when I checked Facebook (FB), the values were returned correctly (https://finance.yahoo.com/q/is?s=FB&annual)。
如果您想创建一个更动态的脚本,您可以使用字符串格式将 url 格式化为您想要的任何股票代码,如下所示:
ticker_symbol = 'AAPL' # or 'FB' or any other ticker symbol
url = 'https://finance.yahoo.com/q/is?s={}&annual'.format(ticker_symbol))