我正在尝试使用以下代码从该网站抓取“每场比赛球队统计数据”表:
from urllib.request import urlopen as uo
from bs4 import BeautifulSoup as BS
import pandas as pd
url = 'https://www.basketball-reference.com/leagues/NBA_2020.html'
html = uo(url)
soup = BS(html, 'html.parser')
soup.findAll('tr')
headers = [th.getText() for th in soup.findAll('tr')]
headers = headers[1:]
print(headers)
rows = soup.findAll('tr')[1:]
team_stats = [[td.getText() for td in rows[i].findAll('td')]
for i in range(len(rows))]
stats = pd.DataFrame(team_stats, columns=headers)
但它返回此错误:
AssertionError: 71 columns passed, passed data had 212 columns
最佳答案
问题在于数据隐藏在 HTML 的注释部分中。您要提取的表是在浏览器中使用 Javascript 呈现的。使用 requests 或 urllib 请求页面只会产生原始 HTML。
因此请注意,如果您使用 BeautifulSoup 搜索正确的标签,则必须使用“查看页面源代码”检查页面的源代码,而不是使用“检查元素”检查渲染的页面。
试试这个:
import requests
from bs4 import BeautifulSoup
import pandas as pd
url = 'https://www.basketball-reference.com/leagues/NBA_2020.html'
html = requests.get(url)
section_start = '<span class="section_anchor" id="team-stats-per_game_link" data-label="Team Per Game Stats">'
block_start = html.text.split(section_start)[1].split("<!--")[1]
block = block_start.split("-->")[0]
soup = BeautifulSoup(block)
data = [th.get_text(",") for th in soup.findAll('tr')]
header = data[0]
header = [x.strip() for x in header.split(",") if x.strip() !=""]
data = [x.split(",") for x in data[1:]]
pd.DataFrame(data, columns=header)
说明:您首先需要通过简单地拆分该部分之前的原始 HTML 来找到注释部分。您将该部分提取为文本,转换为 soup,然后解析。
关于python - 如何从网站上的最后一个表中抓取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59864613/