使用 Python 抓取 Yahoo Finance 的资产负债表

Posted

技术标签:

【中文标题】使用 Python 抓取 Yahoo Finance 的资产负债表【英文标题】:Scraping Yahoo Finance Balance Sheet with Python 【发布时间】:2016-11-30 23:09:48 【问题描述】:

我的问题是here 的后续问题。

功能:

periodic_figure_values()

似乎工作正常,除非正在搜索的订单项的名称出现两次。我所指的具体案例是试图获取“长期债务”的数据。上面链接中的函数会返回如下错误:

Traceback (most recent call last):
  File "test.py", line 31, in <module>
    LongTermDebt=(periodic_figure_values(soup, "Long Term Debt"))
  File "test.py", line 21, in periodic_figure_values
    value = int(str_value)
ValueError: invalid literal for int() with base 10: 'Short/Current Long Term Debt'

因为它似乎被“短期/当前长期债务”绊倒了。您会看到,该页面同时具有“短期/当前长期债务”和“长期债务”。您可以查看使用 Apple 资产负债表 here 的源页面示例。

我正在尝试为函数找到一种方法来返回“长期债务”的数据,而不会被“短期/当前长期债务”绊倒。

以下是获取“现金和现金等价物”的函数和示例,它可以正常工作,而“长期债务”则不能正常工作:

import requests, bs4, re

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)
            values.append(value)
    return values

res = requests.get('https://ca.finance.yahoo.com/q/bs?s=AAPL')
res.raise_for_status
soup = bs4.BeautifulSoup(res.text, 'html.parser')
Cash=(periodic_figure_values(soup, "Cash And Cash Equivalents"))
print(Cash)
LongTermDebt=(periodic_figure_values(soup, "Long Term Debt"))
print(LongTermDebt)

【问题讨论】:

【参考方案1】:

您可以更改函数,使其接受正则表达式而不是纯字符串。然后您可以搜索^Long Term Debt 以确保在此之前没有文本。你需要做的就是改变

if cell.text.strip() != yahoo_figure:

if not re.match(yahoo_figure, cell.text.strip()):

【讨论】:

【参考方案2】:

最简单的方法是使用 try/except 组合并使用提升的ValueError

import requests, bs4, re

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
### from here
            try:
                value = int(str_value)
                values.append(value)
            except ValueError:
                continue
### to here
    return values

res = requests.get('https://ca.finance.yahoo.com/q/bs?s=AAPL')
res.raise_for_status
soup = bs4.BeautifulSoup(res.text, 'html.parser')
Cash=(periodic_figure_values(soup, "Cash And Cash Equivalents"))
print(Cash)
LongTermDebt=(periodic_figure_values(soup, "Long Term Debt"))
print(LongTermDebt)

这个可以很好地打印出你的数字。 请注意,在这种情况下,您实际上并不需要 re 模块,因为您只检查文字(无通配符,无边界)等。

【讨论】:

我正在尝试为函数找到一种方法来返回“长期债务”的数据,而不会被“短期/当前长期债务”绊倒。

以上是关于使用 Python 抓取 Yahoo Finance 的资产负债表的主要内容,如果未能解决你的问题,请参考以下文章

Python零基础入门爬虫原理与数据抓取-通用爬虫和聚焦爬虫

Python零基础入门爬虫原理与数据抓取-通用爬虫和聚焦爬虫

Scrapy使用xpath抓取ul类是行不通的

Ruby中可用的网页抓取宝石/工具[关闭]

Python网络爬虫

python 使用yahoo api的天气预报