【问题标题】:Python Pandas read_html function missing some tables from Pro-Football-ReferencePython Pandas read_html 函数缺少 Pro-Football-Reference 中的一些表格
【发布时间】:2020-12-08 15:40:09
【问题描述】:

我正在尝试从 Python 中的特定网页读取大量表格,并且有点挣扎。我第一次尝试是使用 Pandas read_html,因为它很简单;例如,我将使用这个网站:

https://www.pro-football-reference.com/years/2019/

对于 read_html,我尝试了以下方法:

import pandas as pd

url = 'https://www.pro-football-reference.com/years/2019'

allDfs = pd.read_html(url, header=0)

print(len(allDfs))

这会产生 2 个表的计数。但是,如果您访问该 URL,您会看到有超过 2 个表,并且它们没有被 read_html 函数捕获。

接下来,我尝试使用 requests 和 BeautifulSoup,代码如下:

from bs4 import BeautifulSoup
import requests

url = 'https://www.pro-football-reference.com/years/2019'

r = requests.get(url)

soup = BeautifulSoup(r.content, 'html.parser')

allTables = soup.find_all('table')

print(len(allTables))

这也只输出 2 个表。我将这一步更进一步,并尝试在原始 HTML 中进一步检查其中一个表,该表存在但未找到;在本例中,我将使用“Team Offense”表,该表有一个表标签和一个 ID“team_stats”。但是,此代码返回 0 个找到的表:

from bs4 import BeautifulSoup
import requests

url = 'https://www.pro-football-reference.com/years/2019'

r = requests.get(url)

soup = BeautifulSoup(r.content, 'html.parser')

allTables = soup.find_all('table', attrs={"id":"team_stats"})

print(len(allTables))

最后来到stackoverflow,发现如下问题/回复:
Pandas read_html missing some tables

因此,按照这些指示,我将 urllib.request 与 BeautifulSoup 和 Pandas 结合使用,并且应该能够得到结果...除了我 仍然只得到 2 个表:

import pandas as pd
from bs4 import BeautifulSoup
import urllib.request

html_text = urllib.request.urlopen("https://www.pro-football-reference.com/years/2019/#all_team_stats")
bs_obj = BeautifulSoup(html_text,features='lxml')
tables = bs_obj.findAll('table')
dfs = list()
for table in tables:
    df = pd.read_html(str(table))[0]
    dfs.append(df)

print(len(dfs))

这里有人能帮我弄清楚为什么这些方法都不起作用吗?可以清楚的看到这个页面有很多多于2个表,但是这些方法都找不到。

【问题讨论】:

  • 页面是动态生成的,可能使用ajax。这意味着页面在被实际浏览器访问之前不会完全加载。你可能需要像 selenium 浏览器自动化这样的东西

标签: python pandas web-scraping beautifulsoup


【解决方案1】:

这些表“隐藏”在 HTML 中的 cmets 中,但是,正如其他用户所说,它们似乎是动态加载的。

无论如何,以下是如何获取它们:

import pandas as pd
import requests
from bs4 import BeautifulSoup, Comment

response = requests.get('https://www.pro-football-reference.com/years/2019/')

soup = BeautifulSoup(response.text, 'html.parser')
comments = soup.find_all(string=lambda text: isinstance(text, Comment))

tables = []
for each in comments:
    if 'table' in each:
        try:
            tables.append(pd.read_html(each)[0])
        except:
            continue

print(tables[-1].loc[1:])

例如,这会打印最后一个表Drive Averages

   Unnamed: 0_level_0    Unnamed: 1_level_0  ... Average Drive      
                   Rk                    Tm  ...          Time   Pts
1                 2.0     Carolina Panthers  ...          2:25  1.74
2                 3.0  New England Patriots  ...          2:40  1.97
3                 4.0         New York Jets  ...          2:27  1.23
4                 5.0      Seattle Seahawks  ...          2:40  2.07
5                 6.0   Philadelphia Eagles  ...          2:50  1.96
6                 7.0   Pittsburgh Steelers  ...          2:28  1.40
7                 8.0         Buffalo Bills  ...          2:35  1.63
8                 9.0       New York Giants  ...          2:29  1.75
9                10.0      Tennessee Titans  ...          2:28  2.02
10               11.0      Los Angeles Rams  ...          2:31  1.98
11               12.0         Detroit Lions  ...          2:33  1.77
12               13.0   San Francisco 49ers  ...          2:46  2.44
13               14.0      Cleveland Browns  ...          2:36  1.83
14               15.0        Miami Dolphins  ...          2:32  1.61
15               16.0    Cincinnati Bengals  ...          2:37  1.49
16               17.0     Arizona Cardinals  ...          2:29  2.02
17               18.0     Green Bay Packers  ...          2:51  2.11
18               19.0  Jacksonville Jaguars  ...          2:45  1.63
19               20.0   Washington Redskins  ...          2:28  1.50
20               21.0        Dallas Cowboys  ...          2:42  2.43
21               22.0         Chicago Bears  ...          2:46  1.51
22               23.0       Atlanta Falcons  ...          2:51  2.12
23               24.0    New Orleans Saints  ...          2:59  2.50
24               25.0     Minnesota Vikings  ...          2:40  2.29
25               26.0        Denver Broncos  ...          2:43  1.60
26               27.0        Houston Texans  ...          2:51  2.18
27               28.0    Indianapolis Colts  ...          2:52  2.02
28               29.0      Baltimore Ravens  ...          3:21  2.95
29               30.0       Oakland Raiders  ...          3:00  1.83
30               31.0    Kansas City Chiefs  ...          2:52  2.59
31               32.0  Los Angeles Chargers  ...          3:05  2.06
32                NaN          League Total  ...          2:41  1.94

[32 rows x 12 columns]

Process finished with exit code 0

【讨论】:

  • 非常感谢!对于那些将来阅读这篇文章的人来说,那些代码中不包含 pandas 能够使用 read_html 读取的原始“两个”表,但显然这已经很容易了。有了这个评论以及原始代码,我可以得到我正在寻找的所有表格。
猜你喜欢
  • 2018-03-13
  • 1970-01-01
  • 2022-11-25
  • 1970-01-01
  • 2017-01-07
  • 2017-05-14
  • 1970-01-01
  • 2019-05-06
  • 2021-09-01
相关资源
最近更新 更多