【问题标题】:How to scrape particular data from Yahoo Finance?如何从雅虎财经中抓取特定数据?
【发布时间】:2020-02-25 03:11:40
【问题描述】:

我是网络抓取的新手,我正在尝试为 AAPL 抓取 yahoo Finance 的“统计”页面。这是链接:https://finance.yahoo.com/quote/AAPL/key-statistics?p=AAPL

这是我到目前为止的代码......

from bs4 import BeautifulSoup
from requests import get


url = 'https://finance.yahoo.com/quote/AAPL/key-statistics?p=AAPL'
response = get(url)
soup = BeautifulSoup(response.text, 'html.parser')

stock_data = soup.find_all("table")

for stock in stock_data:
    print(stock.text)

当我运行它时,我会返回页面上的所有表格数据。但是,我只需要每个表中的特定数据(例如“市值”、“收入”、“测试版”)。

我尝试通过执行print(stock[1].text) 来弄乱代码,以查看是否可以将返回的数据量限制为每个表中的第二个值,但这会返回错误消息。使用 BeautifulSoup 是否走在正确的轨道上,还是需要使用完全不同的库?为了只返回特定数据而不是页面上的所有表格数据,我需要做什么?

【问题讨论】:

    标签: python web-scraping beautifulsoup data-science


    【解决方案1】:

    检查 HTML 代码可以让您更好地了解 BeautifulSoup 将如何处理它所看到的内容。

    该网页似乎包含几个表格,这些表格又包含您所需要的信息。这些表格遵循一定的逻辑。

    首先抓取网页上的所有表格,然后找到所有表格行(

    )和这些行包含的表格数据()。

    以下是实现此目的的一种方法。我什至加入了一个只打印特定测量值的功能。

    from bs4 import BeautifulSoup
    from requests import get
    
    
    url = 'https://finance.yahoo.com/quote/AAPL/key-statistics?p=AAPL'
    response = get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    
    stock_data = soup.find_all("table")
    # stock_data will contain multiple tables, next we examine each table one by one
    
    for table in stock_data:
        # Scrape all table rows into variable trs
        trs = table.find_all('tr')
        for tr in trs:
            # Scrape all table data tags into variable tds
            tds = tr.find_all('td')
            # Index 0 of tds will contain the measurement
            print("Measure: {}".format(tds[0].get_text()))
            # Index 1 of tds will contain the value
            print("Value: {}".format(tds[1].get_text()))
            print("")
    
    
    def get_measurement(table_array, measurement):
        for table in table_array:
            trs = table.find_all('tr')
            for tr in trs:
                tds = tr.find_all('td')
                if measurement.lower() in tds[0].get_text().lower():
                    return(tds[1].get_text())
    
    
    # print only one measurement, e.g. operating cash flow
    print(get_measurement(stock_data, "operating cash flow"))
    

    【讨论】:

    • 非常感谢!该代码适用于一个 URL,但是当我尝试实现一个 for 循环以遍历更多 URL 时,我收到了 if measurement.lower() in tds[0].get_text().lower(): 的错误。它说列表索引超出范围。那是因为 UDF “get_measurement” 是一个元组,并且不能遍历 URL 以外的内容吗?
    • get_measurement 是一个接受两个值的函数。发生错误可能是因为 tds-array 为空,因此无法获取索引为 0 的项目。因此,由于某种原因,它没有被填充。使用打印语句找出原因。
    【解决方案2】:

    虽然这不是雅虎财经,但你可以做一些非常类似的事情......

    import requests
    from bs4 import BeautifulSoup
    
    base_url = 'https://finviz.com/screener.ashx?v=152&o=price&t=MSFT,AAPL,SBUX,S,GOOG&o=price&c=0,1,2,3,4,5,6,7,8,9,25,63,64,65,66,67'
    html = requests.get(base_url)
    soup = BeautifulSoup(html.content, "html.parser")
    main_div = soup.find('div', attrs = {'id':'screener-content'})
    
    light_rows = main_div.find_all('tr', class_="table-light-row-cp")
    dark_rows = main_div.find_all('tr', class_="table-dark-row-cp")
    
    data = []
    for rows_set in (light_rows, dark_rows):
        for row in rows_set:
            row_data = []
            for cell in row.find_all('td'):
                val = cell.a.get_text()
                row_data.append(val)
            data.append(row_data)
    
    #   sort rows to maintain original order
    data.sort(key=lambda x: int(x[0]))
    
    import pandas
    pandas.DataFrame(data).to_csv("C:\\your_path\\AAA.csv", header=False)
    

    如果雅虎决定贬低其 API 的更多功能,这是一个很好的替代品。我知道几年前他们删掉了很多东西(主要是历史名言)。看到它消失了,我很难过。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-01
      • 2020-09-10
      • 1970-01-01
      • 1970-01-01
      • 2017-01-14
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多