【问题标题】:Scrape Yahoo Finance Income Statement with Python使用 Python 抓取 Yahoo Finance 损益表
【发布时间】:2016-05-28 02:50:43
【问题描述】:

我正在尝试使用 Python 从Yahoo Finance 的损益表中抓取数据。具体来说,假设我想要most recent figure of Net Income of Apple

数据由一堆嵌套的 HTML 表格构成。我正在使用 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 搜索我需要的数字的名称(在本例中为“净收入”),然后获取数字本身 在 HTML 表的同一行中。

我非常感谢有关如何解决此问题的任何想法,请记住,我想应用该解决方案从其他雅虎财经页面检索大量其他数据。

解决方案/扩展:

@wilbur 下面的解决方案奏效了,我对其进行了扩展,以便能够在 any 的财务页面(即 @987654327 @、Balance SheetCash 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 获取期间结束的日期,并创建一个字典,其中日期是键,数字是值,但这会使这篇文章太长。 到目前为止,这似乎对我有用,但我总是感谢建设性的批评。

【问题讨论】:

    标签: python html beautifulsoup yahoo-finance


    【解决方案1】:

    这有点困难,因为“净收入”包含在 &lt;strong&gt; 标记中,所以请耐心等待,但我认为这可行:

    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,在这种情况下,将包含“净收入”行中的三个表格单元格(并且,我可能会补充说,可以很容易地转换为整数 - 我只是喜欢他们将“,”保留为字符串)

    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),但是当我检查 Facebook (FB) 时,这些值被正确返回了 (@ 987654322@).

    如果你想创建一个更动态的脚本,你可以使用字符串格式化来格式化你想要的任何股票代码的 URL,像这样:

    ticker_symbol = 'AAPL' # or 'FB' or any other ticker symbol
    url = 'https://finance.yahoo.com/q/is?s={}&annual'.format(ticker_symbol))
    

    【讨论】:

    • 非常感谢。到目前为止效果很好。现在我只需要让它更有活力一点。不仅关于股票,还包括同一股票的其他财务数据,以及检查最新数据等。但这是一个很好的开始。
    • AttributeError: 'NoneType' 对象没有属性 'parent'
    猜你喜欢
    • 2022-08-06
    • 2021-03-02
    • 2016-11-30
    • 2014-04-15
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 2013-10-02
    相关资源
    最近更新 更多