在本教程中,我们将学习如何使用read_html() 函数读入HTML表格,以及如何将这些表格变成Pandas数据框架来分析它们。此外,我们将看到如何应用to_html() 函数将潘达斯数据框架渲染成HTML表格。
使用read_html()函数读入HTML表格
那么,让我们开始实际的编码:
import pandas as pd
url = "https://en.wikipedia.org/wiki/Europe"
tables = pd.read_html(url)
print(type(tables))
# <class 'list'>
在开始时,我们导入Pandas 库。然后,我们创建变量"url"并将维基百科页面的URL分配给它,作为一个字符串。之后,我们第一次使用read_html() 函数。我们通过将 "url" 变量放在read_html() 函数中并将其赋值给一个新的变量 "tables" 来读入URL。最后,我们输出 "tables" 的类型。正如我们所看到的,该类型是一个列表。因此,基本上,read_html() 函数,就像我们在这里使用的那样,读入它能在网站上找到的所有表格,并将这些表格作为一个列表分配给变量。
让我们看看有多少个表
print(len(tables))
# 44
我们通过使用函数来确定表格列表的长度 [len()](https://blog.finxter.com/python-len/ "Python len()").总共有44个表。
现在,如果我们想得到一个特定的表,我们可以运行。
print(tables[4])
这就是结果的输出:
| 标志 | 符号 | 名称 | 主权国家 | 面积(平方公里) | 人口 | 人口密度(每平方公里) | 首都 | |
| 0 | 无 | 无 | 阿克罗蒂里和德凯利亚的主权基地地区 | 英国 | 254.0 | 15700 | 59.100 | 埃皮斯科皮营区 |
| 1 | 无 | 不适用 | 奥兰 | 芬兰 | 1580.0 | 29489 | 18.360 | 玛丽港 |
| 2 | 不适用 | 无 | 格恩西岛辖区[c]。 | 英国 | 78.0 | 65849 | 844.000 | 圣彼得港 |
| 3 | 不适用 | 无 | 泽西辖区 [c] | 英国 | 118.2 | 100080 | 819.000 | 圣赫利尔 |
| 4 | 无 | 不适用 | 法罗群岛 | 丹麦 | 1399.0 | 50778 | 35.200 | 托尔斯港 |
| 5 | 瑙 | 不适用 | 直布罗陀 | 英国 | 06.7月 | 32194 | 4.328.000 | 直布罗陀 |
| 6 | 无 | 不适用 | 格陵兰岛 | 丹麦 [r] | 2166086.0 | 55877 | 0.028 | 努克 |
| 7 | NaN | 无 | 马恩岛 [c] | 英国 | 572.0 | 83314 | 148.000 | 道格拉斯 |
| 8 | 无 | 无 | 斯瓦尔巴特群岛 | 挪威 | 61022.0 | 2667 | 0.044 | 朗伊尔城 |
这样,我们就从列表中得到了第五张表。
很好,所以我们已经学会了一种从列表中访问特定表的方法。然而,这种方法并不真正有效,因为如果我们通过列表编号来访问,我们并不知道该表包含什么。幸运的是,read_html() 函数为我们提供了有用的参数来指定我们要访问的表。
比方说,我们想从网站上获得这个表。

由于它是一个表,它包含在我们的 "tables" 列表的某个地方。为了获得这个特定的表,我们使用 "match" 参数。这个参数需要一个字符串或正则表达式作为输入。让我们输入字符串"Peak Year" ,说明我们想访问这个表。
economy_table = pd.read_html(url, match="Peak Year")
# economy_table:

这个输出显示了所有包含字符串"Peak Year" 的表。但我们可以看到,在这个列表中,有两个表。我们可以通过运行来确认这一点。
print(len(economy_table))
# 2
因此,我们需要在我们的"match"参数中更加具体。
economy_table = pd.read_html(url, match="nominal, Peak Year")
# economy_table:

在这里,我们只得到一个表的输出,我们可以再次确认这一点。
print(len(economy_table))
# 1
还有几个参数需要应用。我们将看一下最重要的参数。比方说,我们想把列"GDP (nominal, Peak Year)millions of USD" 中的整数值转换为浮动值。此外,我们可能还想把 "Rank" 列设置为索引列。
economy_table = pd.read_html(url, match="nominal, Peak Year",
converters={"GDP (nominal, Peak Year)millions of USD": float},
index_col=0)
同样,我们像以前一样使用 "match" 参数。除此之外,我们还应用了 "converters" 参数,并放入一个字典 ,以列名为键,以我们要转换的数据类型为值。我们应用了 "index_col" 参数,并将其设置为 "0",说明我们想使用第一列("Rank" 列)作为索引。输出显示了转换后的表。
将表格转换为Pandas数据框架
在我们读取了HTML表格之后,下一步是将这些表格转化为Pandas数据框架,以便能够分析数据。我们上面创建的"economy_table"是来自"list"类型的,并且只包含一个条目。
type(economy_table)
# <class 'list'>
len(economy_table)
# 1
现在,我们想把这个列表条目转换成一个Pandas数据框架。这就是我们如何做的。
economy_df = economy_table[0]
| 国家 | 国内生产总值(名义,高峰年),百万美元 | 峰值年份 | |
| 排名 | |||
| - | 欧盟 | 19226235.0 | 2008 |
| 1 | 德国 | 4230172.0 | 2021 |
| 2 | 英国 | 3108416.0 | 2021 |
| 3 | 法国 | 2940428.0 | 2021 |
| 4 | 意大利 | 2408392.0 | 2008 |
| 5 | 俄罗斯 | 2288428.0 | 2013 |
| 6 | 西班牙 | 1631685.0 | 2008 |
| 7 | 荷兰 | 1007562.0 | 2021 |
| 8 | 土耳其 | 957504.0 | 2013 |
| 9 | 瑞士 | 810830.0 | 2021 |
| 10 | 波兰 | 655332.0 | 2021 |
我们创建一个新的变量 "economy_df" 并将其分配给 "economy_table" 列表的第一个条目。输出的数据框确实是一个Pandas数据框,我们可以通过这样做来证明。
isinstance(economy_df, pd.DataFrame)
# True
所以,这就是我们如何将表转化为数据框架。我们还可以检查每一列的数据类型,看看 "GDP "这一列转换为浮点数是否有效。
economy_df.dtypes
| 国家 | 对象 |
| 国内生产总值(名义,峰值年)百万美元 | float64 |
| 峰值年份 | int64 |
| dtype:对象 |
正如我们所看到的, "GDP" 列的数据类型确实是 "float64"。
所以,现在我们把表转化为Pandas数据框架,我们现在可以做Pandas提供给我们的各种数据分析的东西了。
将数据框架写入HTML表格
现在我们已经看到了如何读入HTML表以及如何将其转化为数据框架,在下一步,我们将看到如何使用to_html() 函数将数据框架写入HTML表。我们将为这种方法使用一个新的数据框架。
data = {
"speed": [7,5,8],
"height": [1.0, 0.3, 0.1],
"length": [1.2, 0.4, 0.2]
}
df = pd.DataFrame(data, index=["dog", "cat", "fish"])
这是新创建的数据框架。
| 速度 | 高度 | 长度 | |
| 狗 | 7 | 1.0 | 1.2 |
| 猫 | 5 | 0.3 | 0.4 |
| 鱼类 | 8 | 0.1 | 0.2 |
在这里,我们有一个例子数据集,其中有一个"speed",一个"height",和一个"length"列。我们用这些数据创建了一个名为 "df"的Pandas数据框,并为其分配了 "狗"、"猫 "和 "鱼 "的索引。输出显示了一个普通的Pandas数据框。
接下来,我们应用to_html() 函数。
html_table = df.to_html()
print(html_table)
这里是输出的HTML表格
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>speed</th>
<th>height</th>
<th>length</th>
</tr>
</thead>
<tbody>
<tr>
<th>dog</th>
<td>7</td>
<td>1.0</td>
<td>1.2</td>
</tr>
<tr>
<th>cat</th>
<td>5</td>
<td>0.3</td>
<td>0.4</td>
</tr>
<tr>
<th>fish</th>
<td>8</td>
<td>0.1</td>
<td>0.2</td>
</tr>
</tbody>
</table>
我们使用to_html() 将 "df" 渲染成一个 HTML 表格,并将其分配给新的变量 "html_table"。我们使用 [print()](https://blog.finxter.com/python-print/ "Python print()")语句进行输出,因为否则,输出会很混乱。输出结果显示了一个经典的HTML表格。
除此之外,我们还可以把这个HTML表写到一个文件里。
html_file = open("index.html", "w")
html_file.write(html_table)
html_file.close()
这样,我们就创建了一个名为 "index.html "的HTML文件,并将其与我们正在处理的python文件存放在同一个文件夹中。当我们进入这个文件夹,用浏览器打开这个HTML文件时,它看起来是这样的。

然而,我们使用的方法是将"[open](https://blog.finxter.com/python-open-function/ "Python open() Function — An 80/20 Guide By Example")", "[write](https://blog.finxter.com/python-one-liner-write-string-to-file/ "Python One-Liner: Write String to File")"和"[close](https://blog.finxter.com/simple-guide-to-python-close/ "Simple Guide to Python close()")"语句有点啰嗦,而且不干净。幸运的是,Python为我们提供了一个很好的替代方案,使我们的代码更加简洁。
with open("index.html", "w") as file:
file.write(html_table)
在这里,我们使用了 "with "语句,它用于异常处理。它的作用与上面的例子相同,但这样做更顺畅,因为我们需要的代码更少,而且更容易阅读。
塑造HTML表格的风格
to_html() 函数为我们提供了一些可选的参数,我们可以应用这些参数来为我们的HTML表格添加一些样式。例如,我们可以使用"justify"参数来调整列的标签。
html_table = df.to_html(justify="center")
print(html_table)
输出的HTML
<table border="1" class="dataframe">
<thead>
<tr style="text-align: center;">
<th></th>
<th>speed</th>
<th>height</th>
<th>length</th>
</tr>
</thead>
<tbody>
<tr>
<th>dog</th>
<td>7</td>
<td>1.0</td>
<td>1.2</td>
</tr>
<tr>
<th>cat</th>
<td>5</td>
<td>0.3</td>
<td>0.4</td>
</tr>
<tr>
<th>fish</th>
<td>8</td>
<td>0.1</td>
<td>0.2</td>
</tr>
</tbody>
</table>
如果我们将这个HTML表格与上面的表格进行比较,我们可以看到在"tr style"标签中的"text-align"现在写的是"center"而不是"right",因为默认值是"right"。
我们还可以通过应用 "border" 参数,将默认的边框大小 "1 "改为另一个值。
html_table = df.to_html(justify="center", border=4)
print(html_table)
这就是输出结果
<table border="4" class="dataframe">
<thead>
<tr style="text-align: center;">
<th></th>
<th>speed</th>
<th>height</th>
<th>length</th>
</tr>
</thead>
<tbody>
<tr>
<th>dog</th>
<td>7</td>
<td>1.0</td>
<td>1.2</td>
</tr>
<tr>
<th>cat</th>
<td>5</td>
<td>0.3</td>
<td>0.4</td>
</tr>
<tr>
<th>fish</th>
<td>8</td>
<td>0.1</td>
<td>0.2</td>
</tr>
</tbody>
</table>
现在,"table border" 标签显示 "4 "而不是 "1"。
如果我们使用CSS id选择器,我们可以使用参数"table_id"在to_html() 函数中直接应用这些选择器。
html_table = df.to_html(justify="center", border= 4, table_id="animal table")
print(html_table)
这就是结果表
<table border="4" class="dataframe" id="animal table">
<thead>
<tr style="text-align: center;">
<th></th>
<th>speed</th>
<th>height</th>
<th>length</th>
</tr>
</thead>
<tbody>
<tr>
<th>dog</th>
<td>7</td>
<td>1.0</td>
<td>1.2</td>
</tr>
<tr>
<th>cat</th>
<td>5</td>
<td>0.3</td>
<td>0.4</td>
</tr>
<tr>
<th>fish</th>
<td>8</td>
<td>0.1</td>
<td>0.2</td>
</tr>
</tbody>
</table>
在第一个标签中,我们现在有一个id选择器元素,而我们以前没有。
总结
总而言之,Pandas为我们提供了一些有用的工具,可以在处理HTML表格时使用。我们可以通过read_html() 函数很容易地从网站上直接读入HTML表格,并从这些表格中创建数据框架。此外,我们还可以将我们的数据框架渲染成HTML表格,对这些表格应用一些样式,并将其保存为HTML文件。这些技能是非常重要的,尤其是在处理网络数据的时候。