首页 > 解决方案 > 如何从具有请求和 BeautifulSoup4 的动态内容的网站中提取表格数据?

问题描述

我在从该页面提取表格时遇到了一些问题:www.nasdaq.com/market-activity/stocks/aapl/dividend-history

我的代码是:

import requests
from bs4 import BeautifulSoup

headers = {'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'}
page = requests.get("https://www.nasdaq.com/market-activity/stocks/aapl/dividend-history", headers=headers)
soup = BeautifulSoup(page.content, 'html.parser')

table = soup.find('table', attrs={'class':'dividend-history__table'})
table_body = table.find('tbody', attrs={'class': 'dividend-history__table-body'})
data = []
rows = table_body.find('tr', attrs={'class': 'dividend-history__row dividend-history__row--data'})
for row in rows:
    cols = row.find('td')
    cols = [ele.text.strip() for ele in cols]
    data.append([ele for ele in cols if ele]) # Get rid of empty values

他们在 iframe 中有表格。我不确定我做错了什么——这是我第一次使用 BeautifulSoup——我通常使用 requests + xPath 来处理这类事情。

标签: pythonbeautifulsouppython-requestsscrapy

解决方案


怎么了?

  1. 如您所料,表格不在 iframe 中。
  2. 表数据是动态生成的,因此您无法使用您的方法获取它
  3. 如果内容是静态的,那么在这行之前一切都可以正常工作。

看看find()只得到你的过滤器的第一次出现 - 只有一个<tr>你应该使用find_all()

rows = table_body.find('tr', attrs={'class': 'dividend-history__row dividend-history__row--data'})

您尝试循环一个不可迭代的:

for row in rows:

同样的事情find()

cols = row.find('td')

并再次迭代一个不可迭代的:

cols = [ele.text.strip() for ele in cols]

替代方案呢?

从网站上抓取数据有不同的方法,requests如果它们处理动态数据,您经常会遇到限制。

使用网站api怎么样?

使用 requests 和 pandas 可以很简单:

import requests
import pandas as pd

url = "https://api.nasdaq.com/api/quote/AAPL/dividends?assetclass=stocks"
headers = {"user-agent": "Mozilla/5.0"}

r = requests.get(url, headers=headers)

df = pd.json_normalize(r.json()['data']['dividends']['rows'])
df

输出

exOrEffDate type    amount  declarationDate recordDate  paymentDate

11/06/2020  CASH    $0.205  10/29/2020  11/09/2020  11/12/2020
08/07/2020  CASH    $0.82   07/30/2020  08/10/2020  08/13/2020
05/08/2020  CASH    $0.82   04/30/2020  05/11/2020  05/14/2020
02/07/2020  CASH    $0.77   01/28/2020  02/10/2020  02/13/2020
11/07/2019  CASH    $0.77   10/30/2019  11/11/2019  11/14/2019

推荐阅读