【问题标题】:Not return all the tables不返回所有表格
【发布时间】:2020-10-15 00:50:29
【问题描述】:

我想尝试从this website 中抓取所有表格。该网站包含多个10 表格。当我使用pd.read_html() 时,它只返回3 个表格,但我希望我的脚本返回所有表格。 我的脚本:

import pandas as pd
url = "https://aws.pro-football-reference.com/teams/mia/2000.htm"
df = pd.read_html(url)
len(df)

输出:

3

特别想要这张桌子:

如何使用pd.read_html() 获取所有表格?

【问题讨论】:

  • 当我在网络浏览器中查看链接时,我看到了 3 个表格:一个标题为 Team Stats and Rankings ,一个标题为 Schedule & Game Results ,另一个标题为 Team Conversions 。应该还有什么?
  • @KarlKnechtel 先生,上面的链接为我的案例显示更多表格,如Team Stats and RankingsSchedule & Game ResultsTeam ConversionsPassingRushing & Receiving 等等。甚至,就是上面的图片
  • @HumayunAhmadRajib 许多现代网站使用 JavaScript 动态加载内容。当您请求 HTML 时,它可能会返回到目前为止已加载的所有内容。我不确定read_html() 到底是如何工作的,但您可以探索其他选项来获取完全加载的 HTML,然后使用 pandas 进行处理。
  • @gallen 先生,我得到了三张桌子,为什么我不能得到其余的。
  • @HumayunAhmadRajib 因为在read_html() 发出的请求完成时,页面上只呈现了3 个表格。如果渲染过程的加载时间比爬虫等待读取的时间长,您将丢失数据。这就是为什么我建议不要依赖黑盒函数来做,而是自己刮然后处理。

标签: python python-3.x pandas web-scraping html-table


【解决方案1】:

pd.read_html 在后台使用 BeautifulSoup 从网页中抓取 <table> 元素。使用requests抓取网页的HTML并手动解析,我发现你链接的页面确实只包含三个<table>元素。但是,可以在 HTML cmets 中找到几个附加表(包括您想要的“踢”表)的数据。

解决方案

解析注释掉的表格。

import requests
import bs4
import pandas as pd

url = "https://aws.pro-football-reference.com/teams/mia/2000.htm"
scraped_html = requests.get(url)
soup = bs4.BeautifulSoup(scraped_html.content)

# Get all html comments, then filter out everything that isn't a table
comments = soup.find_all(text=lambda text:isinstance(text, bs4.Comment))
commented_out_tables = [bs4.BeautifulSoup(cmt).find_all('table') for cmt in comments]
# Some of the entries in `commented_out_tables` are empty lists. Remove them.
commented_out_tables = [tab[0] for tab in commented_out_tables if len(tab) == 1]

print(len(commented_out_tables))

8

其中只有一个是“踢”桌。我们可以通过查找id 属性设置为kickingtable 来找到它。

for table in commented_out_tables:
    if table.get('id') == 'kicking':
        kicking_table = table
        break

把它变成pd.DataFramepd.read_html

pd.read_html(str(kicking_table))

产生以下结果:

[  Unnamed: 0_level_0 Unnamed: 1_level_0 Unnamed: 2_level_0 Unnamed: 3_level_0 Games       ... Kickoffs Punting
                  No.             Player                Age                Pos     G   GS  ...    KOAvg     Pnt     Yds   Lng Blck   Y/P
 0                1.0          Matt Turk               32.0                  p    16  0.0  ...      NaN    92.0  3870.0  70.0  0.0  42.1
 1               10.0        Olindo Mare               27.0                  k    16  0.0  ...     60.3     NaN     NaN   NaN  NaN   NaN
 2                NaN         Team Total               27.3                NaN    16  NaN  ...     60.3    92.0  3870.0  70.0  0.0  42.1
 3                NaN          Opp Total                NaN                NaN    16  NaN  ...      NaN    87.0  3532.0   NaN  NaN  40.6

 [4 rows x 32 columns]]

【讨论】:

  • 仅供参考,因为 oyu 提到了它,pd.read_html() 在引擎盖下使用了 beautifulsoup。它解析出<table><th><tr><td> 标签,但正如您所注意到的,它不会费心检查 cmets。所以就像你说的,最初只找到 3 个<table> 元素,然后你必须从 cmets 中取出那些其他元素。干得好!
  • 感谢您让我知道@chitown88!我已经编辑了我的答案,将这些信息包含在上下文中。
猜你喜欢
  • 2016-04-25
  • 2018-05-18
  • 2017-10-06
  • 2018-10-28
  • 2019-08-12
  • 2019-05-26
  • 1970-01-01
  • 2016-03-27
  • 2014-10-05
相关资源
最近更新 更多