使用 Pandas read_html 函数读取 HTML 表格

2023-10-18

您可以使用read_html直接从网站抓取 HTML 表格并将其转换为数据框。它简化了从网页提取数据的过程。
The read_html函数接受一个包含 URL 或指向 HTML 文件的文件路径的字符串,提取该 HTML 页面中包含的所有表,并返回 DataFrame 列表。

每个 DataFrame 对应 HTML 页面上的一个表。
默认情况下,read_html函数使用 lxml、BeautifulSoup 和 html5lib 库来解析 HTML 页面。

这意味着您需要在 Python 环境中安装这些库才能使用此功能。


!pip install lxml beautifulsoup4 html5lib
  

 

 

语法和参数

The read_html函数于Pandas非常灵活,允许多个参数来控制数据提取。该函数的语法如下:


pandas.read_html(io, match='.+', flavor=None, header=None, index_col=None, skiprows=None, attrs=None, parse_dates=False, thousands=', ', encoding=None, decimal='.', converters=None, na_values=None, keep_default_na=True, displayed_only=True)
  

下面简单解释一下参数:

  • io:此参数采用一个字符串,可以是 URL、文件路径或 HTML 内容。
  • match:这是表应该匹配才能提取的正则表达式。默认值为‘.+’,表示提取所有表。
  • flavor:在引擎盖下使用的解析引擎。默认为None它使用“lxml”和“beautiful soup”,但您也可以指定“html5lib”。
  • header:此参数采用一个整数或整数序列,用于定义用作列名称的行。默认为None这意味着列名是从表标题行推断出来的。
  • index_col:这需要一个整数或整数序列来定义要设置为索引(MultiIndex)的列。
  • skiprows:此参数采用一个整数或整数序列来跳过指定的行。
  • attrs:这是表格标签应包含的 HTML 属性的字典。
  • parse_dates:该参数用于自动解析表中的日期。它默认为False.
  • converters, na_values这些分别是用于转换数据和 NA 值的其他参数。

重要的是要注意read_html函数返回 DataFrame 列表。

 

使用 Pandas read_html 提取 HTML 表

The pandas.read_html函数允许您从本地 HTML 文件、URL 或任何包含 HTML 的类似文件的对象中提取表。

从本地 HTML 文件中提取表

假设您有一个 HTML 文件(样本1.html)与 Python 文件位于同一目录中,它包含两个简单的表。

现在,让我们使用以下命令从该页面读取 HTML 表read_html:

import pandas as pd
file_path = "sample.html"
tables = pd.read_html(file_path)
  

让我们检查表的数量并显示第一个表:


print("Number of tables in file: ", len(tables))
print("First table:")
print(tables[0])
  

Output:


Number of tables in file:  2
First table:
   Header 1  Header 2  Header 3
0  Data 1.1  Data 1.2  Data 1.3
1  Data 2.1  Data 2.2  Data 2.3
2  Data 3.1  Data 3.2  Data 3.3
  

输出将显示 HTML 文件中的表格数量以及第一个表格的内容。

从 URL 中提取数据

我们将从维基百科的“按人口统计的国家和附属国列表”中提取数据。


import pandas as pd
url = "https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population"
tables = pd.read_html(url)
  

The pd.read_html(url)函数返回 DataFrame 列表。以下是我们如何检查表的数量并显示第一个表:


print("Number of tables on site: ", len(tables))
print("First table:")
print(tables[0])
  

Output:


Number of tables on site:  3
First table:
    0                                                  1
0 NaN  This article needs to be updated. The reason g...
  

如您所见,输出是页面中的第一个表。您可能会注意到这不是我们感兴趣的表格(按人口排列的国家/地区)。

这是因为我们正在抓取的页面包含多个表。您可以指定正确的索引,但还有另一种方法可以指定要提取的表。这可以通过使用 HTML 属性来完成。

 

使用表 HTML 属性

如果表格具有 HTML 属性,例如id or class,您可以使用它们来提取特定的表。
The attrs参数输入read_html接受要匹配的属性字典。然后,该函数仅提取具有匹配属性的表。
让我们看一个如何使用的例子attrs:


url = "https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population"
tables = pd.read_html(url, attrs={"class": "wikitable"})
df = tables[0]
  

与提取所有表然后挑选出您需要的表相比,这是一种更有针对性的表提取方式。
请记住,属性名称和值区分大小写,并且必须与 HTML 源中的名称和值完全匹配,但是如果表没有属性并且我们想要有针对性的方式怎么办?

 

使用正则表达式进行抓取

Pandas read_html函数提供了match参数允许我们使用正则表达式根据内容匹配特定的表。

当网页或文件有大量没有属性的表,并且我们希望根据某些条件过滤表时,这特别有用。
如果您查看我们正在抓取的维基百科页面,您会注意到我们需要抓取的表是唯一包含“美国”一词的表:


import pandas as pd
url = "https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population"
tables = pd.read_html(url, match='United States')
  

检查与正则表达式匹配的表的数量并显示第一个表:


print("Number of matched tables on site: ", len(tables))
print("First matched table:")
print(tables[0])
  

Output:


Number of matched tables on site:  1
First matched table:
    Rank  ... Notes   
...
  

该表包含国家及其人口详细信息。
您需要使用有效的索引来访问特定的 DataFrame。如果没有表与正则表达式匹配,则ValueError将被提高。

 

处理不一致的表结构

处理 HTML 表格时,您可能会遇到带有合并单元格或嵌套表格(表格中的表格)的表格。让我们看看如何read_html函数将处理这些。

合并单元格

对于水平合并的单元格(跨越多列的单元格)或垂直合并的单元格(跨越多行的单元格),Pandas 将在跨越的列中重复单元格值。

这是一个带有水平合并单元格的 HTML 表格:


<table>
<tr>
<td colspan="2">Merged</td>
<td>Regular</td>
</tr>
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
</table>  

当我们使用read_html解析此 HTML:


df = pd.read_html('sample.html')[0]
print(df)
  

Output:


   0       1       2
0  Merged  Merged  Regular
1  A       B       C
  

正如您所看到的,合并的单元格值(“合并”)已在两个跨列中重复。

这是一个带有垂直合并单元格的 HTML 表格:


<table>
<tr>
<td rowspan="2">Merged</td>
<td>Regular</td>
</tr>
<tr>
<td>C</td>
</tr>
</table>  

当我们使用read_html解析此 HTML:


df = pd.read_html(sample.html)[0]
print(df)
  

Output:


        0        1
0   Merged  Regular
1   Merged     C
  

在这种情况下,合并的单元格值(“合并”)在两个跨行中重复。

嵌套表

对于嵌套表,read_html自动分离外表和内表。每个表都成为返回列表中的一个单独的 DataFrame。

假设您有嵌套的 HTML 表 (嵌套 HTML 示例).

当我们跑步时read_html相反,它返回两个表,外部表和内部表:


tables = pd.read_html('nested_tables.html')
print(tables[0])  

Output:


  Header 1 Header 2                                           Header 3
0   Data 1   Data 2  Nested Header 1  Nested Header 2  Nested Data ...
1   Data 3   Data 4                                             Data 5
  

这是外面的桌子。

对于内表:


tables = pd.read_html('nested_tables.html')
print(tables[1])  

Output:


  Nested Header 1 Nested Header 2
0   Nested Data 1   Nested Data 2
1   Nested Data 3   Nested Data 4
  

 

设置自定义 NA 值

The na_values中的参数read_html函数允许您指定此类自定义 NA 值。该函数将替换这些NaN生成的 DataFrame 中的值。

考虑一个 HTML 表格,其中空单元格由单词“Empty”和“Blank”表示(na_values 样本)

这是如何使用的示例na_values:


na_values = ['Empty', 'Blank']
tables = pd.read_html('na_values.html', na_values=na_values)  

Output:


  Header 1 Header 2 Header 3
0   Data 1      NaN   Data 3
1   Data 4      NaN   Data 6
2   Data 7   Data 8   Data 9
  

现在,当 Pandas 遇到任何指定值时na_values在解析 HTML 表时,它将把它们视为NaN.

 

设置索引

使用时read_html,您可以指定index_col参数,在表提取过程中直接将某一列设置为DataFrame的索引。

这可以节省您额外的致电步骤set_index然后。
The index_col参数采用一个整数或整数序列,表示要设置为索引的列号。列号从 0 开始。
使用方法如下:


url = "https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population"
tables = pd.read_html(url, index_col=1, match='Notes')
df = tables[0]
  

这里我们使用了match='Notes'因为我们要使用的表是唯一包含该单词的表。

现在,“Country”在表提取时直接设置为DataFrame的索引。您可以使用国家/地区名称来访问特定行:


print(df.loc['United States'])
  

Output:


Country / Dependency                          Country / Dependency                        
Rank                                          Rank                                                                       3
Population                                    Numbers                                                            334933000
                                              % of the world                                                           NaN
Date                                          Date                                                             25 Jun 2023
Source (official or from the United Nations)  Source (official or from the United Nations)    National population clock[7]
Notes                                         Notes                                                                    [d]
  

通过使用index_col in read_html,您可以简化数据提取和准备过程。

 

设置标题

In read_html,您可以使用header参数指定表中的哪一行用作列标题。当表标题不在第一行或表具有多个标题行时,这尤其有用。
The header参数接受一个整数或一个整数列表,表示要用作标题的行号。请记住,行号从 0 开始。
假设表格的标题位于第二行(索引 1):


url = "https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population"
tables = pd.read_html(url, header=1, match='Notes')
df = tables[0]
  

这将使表中的第二行作为标题。

在多个标头的情况下,您可以传递整数列表:


tables = pd.read_html(url, header=[0, 1])
df = tables[0]
  

 

跳行

The skiprows参数输入read_html允许您指定要跳过的行。
它需要一个整数或一个整数序列来表示要跳过的行号。
这是一个例子:


url = "https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population"
tables = pd.read_html(url, skiprows=0, match='Notes')
df = tables[0]
  

生成的 DataFrame 将不包含表的第一行。

您还可以通过传递列表来跳过多个不连续的行:


tables = pd.read_html(url, skiprows=[0, 2])
  

 

转变内容

您可能想要删除测量单位、将字符串转换为整数或应用某些其他转换。

您可以使用以下方法实现此目的converters参数输入read_html.
The converters参数接受一个字典,其中键是列名或列号,值是将应用于相应列中每个值的函数。
考虑一个带有百分比的 HTMl 表 (转换器样本):

让我们定义一个函数来从百分比列中删除“%”:


def convert_percent(val):
    new_val = val.replace('%', '')
    return float(new_val)

tables = pd.read_html('converters.html', converters={'Percentage': convert_percent})
df = tables[0]
  

Output:


  Header 1 Header 2  Percentage
0   Data 1   Data 2        25.0
1   Data 3   Data 4        50.0
2   Data 5   Data 6        75.0
  

 

提取链接

The extract_links中的参数read_html函数允许从 HTML 表数据中提取超链接。

该参数接受多个值:None, "all", "header", "body", and "footer".

  1. None: 这是默认选项。不提取任何链接,并且链接文本作为常规单元格值包含在内。
  2. “all”:从表的所有部分提取链接。每个包含链接的单元格都表示为一个元组,其中第一个元素是单元格文本,第二个元素是链接。
  3. “header”: 仅表头中的链接(内部<th>元素)被提取。
  4. “body”:仅表体中的链接(内部<td>元素)被提取。
  5. “footer”:仅表页脚中的链接(内部<tfoot>元素)被提取。

考虑一个 HTML 表,其中在页眉、正文和页脚中包含链接(提取链接样本):

仅从标题中提取链接:

tables = pd.read_html('extract_links.html', extract_links='header')
df = tables[0]  

Output:


  (Header Link, https://example.com) (Header 2, None) (Header 3, None)
0                          Body Link           Data 2           Data 3
1                             Data 4           Data 5           Data 6
2                             Data 7           Data 8      Footer Link
  

仅从正文链接中提取链接:


tables = pd.read_html('extract_links.html', extract_links='body')
df = tables[0]  

Output:


                        Header Link        Header 2        Header 3
0  (Body Link, https://example.com)  (Data 2, None)  (Data 3, None)
1                    (Data 4, None)  (Data 5, None)  (Data 6, None)
2                            Data 7          Data 8     Footer Link
  

仅提取页脚链接:


tables = pd.read_html('extract_links.html', extract_links='footer')
df = tables[0]  

Output:


      Header Link        Header 2                            Header 3
0       Body Link          Data 2                              Data 3
1          Data 4          Data 5                              Data 6
2  (Data 7, None)  (Data 8, None)  (Footer Link, https://example.com)
  

要提取所有链接:


  (Header Link, https://example.com)  ...                    (Header 3, None)
0   (Body Link, https://example.com)  ...                      (Data 3, None)
1                     (Data 4, None)  ...                      (Data 6, None)
2                     (Data 7, None)  ...  (Footer Link, https://example.com)
  

请注意,此功能从 Pandas 1.3.0 版本开始可用。

 

pandas.read_html() 限制

以下是其他一些潜在的限制pandas.read_html:

  1. 无动态内容: read_html无法处理动态加载的内容。如果网站的内容根据用户交互而更改或在初始页面加载后加载(如无限滚动),则read_html将无法捕获此数据。
  2. 无需提交表单或进行身份验证:如果页面需要用户交互,例如表单提交或身份验证,read_html无法执行这些操作。
  3. 有限的 CSS 选择器支持:它不支持特定或复杂的 CSS 选择器。因此,如果您需要选择网页中非严格表格的非常特定的部分,那么read_html可能还不够。
  4. 没有多页抓取:如果您感兴趣的数据分布在多个页面(分页),read_html将无法自动遍历这些页面。
  5. 无法处理非表格数据:如果您感兴趣的数据不是表格格式(例如段落、标题、列表等),read_html将无法提取它。
  6. 标头和 Cookie:Web 抓取库(如 requests、Beautiful Soup 和 Selenium)提供了对 HTTP 标头和 cookie 的更多控制,这在处理需要设置某些标头或 cookie 的网站时至关重要。
  7. Robots.txt 尊重:Scrapy 等网络抓取工具遵守网站 robots.txt 文件中设置的规则。这是道德网络抓取的一个重要方面,但不是由pandas.read_html.

但是,您可以使用 Python 网页抓取克服 pandas.read_html 限制.

 

进一步阅读

https://pandas.pydata.org/docs/reference/api/pandas.read_html.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Pandas read_html 函数读取 HTML 表格 的相关文章

随机推荐

  • 使用 Python 函数

    在编程时 我们经常重复执行相同的任务 例如执行数字加法或使用不同的输入打印相同的语句 这些是一般示例 但对于这些示例 您愿意编写相同的代码 10 次还是只编写一次 这就是函数的目的 它们是仅针对特定任务定义一次的代码片段 并具有可重用的功能
  • 在 HDFS 中创建目录并复制文件 (Hadoop)

    HDFS is the Hadoop分布式文件系统 它是一个用于大型数据集的分布式存储系统 支持容错 高吞吐量和可扩展性 它的工作原理是将数据划分为在集群中的多台机器上复制的块 这些块可以并行写入或读取 从而提高吞吐量和容错能力 HDFS
  • 如何在 Debian 11/10/9 上安装 Gulp.js

    Gulp是一个工具包 可帮助开发人员在开发过程中实现痛苦工作流程的自动化 本教程将帮助您在 Debian 11 Debian 10 和 Debian 9 操作系统上安装 Gulp 第 1 步 安装 Node js 首先 你需要安装node
  • 如何在 Linux 中递归更改文件的权限

    如果您使用 Linux 作为主要操作系统或管理 Linux 服务器 您会遇到尝试创建或编辑文件并收到 权限拒绝 错误的情况 通常 与权限不足相关的错误可以通过设置正确的文件权限或所有权 Linux 是一个多用户系统 对文件的访问是通过文件权
  • 如何显示 MySQL 中所有数据库的列表

    给药时MySQL对于数据库服务器 您要做的最常见的任务之一就是熟悉环境 这涉及诸如列出驻留在服务器上的数据库等任务 显示表格特定数据库的信息或获取有关用户帐户及其权限的信息 本教程介绍如何通过命令行显示 MySQL 或 MariaDB 服务
  • 如何创建 Tar Gz 文件

    tar 存档是一个存储其他文件集合的文件 包括有关这些文件的信息 例如所有权 权限和时间戳 在 Linux 操作系统中 您可以使用tar创建 tar 档案的命令 该命令还可以使用各种压缩程序来压缩档案 其中 gzip 是最流行的算法 按照约
  • 如何在 Ubuntu 20.04 上安装 GCC (build-essential)

    GNU 编译器集合 GCC 是 C C Objective C Fortran Ada Go D 编程语言 很多开源项目 包括Linux内核和GNU工具 都是使用GCC编译的 本文介绍如何在 Ubuntu 20 04 上安装 GCC 在 U
  • 如何在 Debian 9 上安装和使用 FFmpeg

    FFmpeg 是一个免费的开源命令行工具 用于对多媒体文件进行转码 它包含一组共享的音频和视频库 例如libavcodec libavformat和libavutil 使用 FFmpeg 您可以在各种视频和音频格式之间进行转换 设置采样率以
  • 如何在 Ubuntu 18.04 上安装 Python 3.7

    Python 是世界上最流行的编程语言之一 凭借其简单易学的语法 Python 是初学者和经验丰富的开发人员的绝佳选择 Python 是一种非常通用的编程语言 它可以用作脚本语言来构建游戏 开发网站 创建机器学习算法和分析数据 Python
  • 如何在 CentOS 7 上安装 VLC 媒体播放器

    VLC 是一种流行的开源多媒体播放器和流媒体服务器 它是跨平台的 几乎可以播放所有多媒体文件以及 DVD 音频 CD 和不同的流媒体协议 本教程介绍如何在 CentOS 7 上安装 VLC 媒体播放器 先决条件 您需要以以下身份登录具有 s
  • 如何在 Ubuntu 20.04 上安装和使用 FFmpeg

    FFmpeg 是一个用于处理多媒体文件的免费开源工具集合 它包含一组共享的音频和视频库 例如libavcodec libavformat和libavutil 使用 FFmpeg 您可以在各种视频和音频格式之间进行转换 设置采样率 捕获流音频
  • Linux 睡眠命令(暂停 Bash 脚本)

    sleep是一个命令行实用程序 允许您将调用进程挂起指定的时间 换句话说 sleep命令将下一个命令的执行暂停给定的秒数 The sleep该命令在 bash shell 脚本中使用时非常有用 例如 在重试失败的操作或在循环内时 在本教程中
  • 如何在 Ubuntu 18.04 上安装 CouchDB

    CouchDB 是由 Apache 软件基金会维护的免费开源容错 NoSQL 数据库 CouchDB 服务器将其数据存储在命名数据库中 其中包含以下文档JSON结构 每个文档由许多字段和附件组成 字段可以包括文本 数字 列表 布尔值等 它包
  • 如何在 Debian 10 上安装 Xrdp 服务器(远程桌面)

    Xrdp 是 Microsoft 远程桌面协议 RDP 的开源实现 允许您以图形方式控制远程系统 使用 RDP 您可以登录到远程计算机并创建真实的桌面会话 就像登录到本地计算机一样 本教程介绍如何在 Debian 10 Linux 上安装和
  • 如何使用SFTP命令传输文件

    SFTP SSH 文件传输协议 是一种安全文件协议 用于通过加密的 SSH 传输访问 管理和传输文件 与传统的相比FTPSFTP 提供 FTP 的所有功能 但更安全且更易于配置 Unlike SCPSFTP 仅支持文件传输 但允许您对远程文
  • 15+ yum update 命令示例

    Yum 是 Red Hat CentOS 和其他操作系统上使用的包管理器Linux 发行版使用 RPM 包管理器 Yum 用于安装 更新 删除或以其他方式操作这些 Linux 系统上安装的软件包 在本教程中 我们将介绍 yum update
  • Seaborn barplot 教程(以条形图可视化您的数据)

    数据可视化已成为与分析数据进行交流的重要阶段 通过数据可视化 数据科学家和业务分析师可以轻松地从大量数据中提取见解 Seaborn 是一种 Python 中的统计图形绘图和可视化库 允许数据分析师和数据科学专业人员呈现可视化 在本文中 我们
  • 15 个 Linux 读取命令示例

    The readLinux 中的命令允许您从标准输入或文件中读取输入 它允许您接收数据并将其分配给变量 本教程将指导您完成不同的选项read命令 目录 hide 1 读取用户的输入 2 从文件中读取输入 3 指定分隔符
  • 创建和使用动态 Laravel 子域路由

    许多网站为用户的个人资料或页面提供了一个自定义子域 因此用户可以通过 http username website com 访问他的个人资料 这要好得多 在这篇文章中 我们将了解如何高效地进行动态 Laravel 子域路由 配置DNS 要做到
  • 使用 Pandas read_html 函数读取 HTML 表格

    您可以使用read html直接从网站抓取 HTML 表格并将其转换为数据框 它简化了从网页提取数据的过程 The read html函数接受一个包含 URL 或指向 HTML 文件的文件路径的字符串 提取该 HTML 页面中包含的所有表