Beautiful Soup 简明教程
Beautiful Soup - Parsing Tables
除了文本内容,HTML 文档还可能具有 HTML 表格形式的结构化数据。借助 Beautiful Soup,我们可以将表格数据提取为 Python 对象(例如列表或字典),如果需要,可以将这些数据存储在数据库或电子表格中,然后再执行处理操作。在本章中,我们将使用 Beautiful Soup 解析 HTML 表格。
虽然 Beautiful Soup 没有用于提取表格数据的任何特殊函数或方法,但我们可以通过一些简单的抓取技巧来实现此目的。就像 SQL 或电子表格中的任何表格一样,HTML 表格包含行和列。
HTML 中使用 <table> 标签来构建一个表格结构。有一个或多个嵌套 <tr> 标签,每个标签对应一行。每一行由 <td> 标签组成,这些标签用于保存行中每个单元格中的数据。第一行通常用于列标题,且标题不放在 <td> 标签中,而是放在 <th> 标签中
以下 HTML 脚本在浏览器窗口中呈现一个简单的表格 −
<html>
<body>
<h2>Beautiful Soup - Parse Table</h2>
<table border="1">
<tr>
<th>Name</th>
<th>Age</th>
<th>Marks</th>
</tr>
<tr class='data'>
<td>Ravi</td>
<td>23</td>
<td>67</td>
</tr>
<tr class='data'>
<td>Anil</td>
<td>27</td>
<td>84</td>
</tr>
</table>
</body>
</html>
请注意,数据行的外观是使用 CSS 类 data 自定义的,用于将其与标题行区分开来。
我们现在来看如何解析表格数据。首先,我们在 BeautifulSoup 对象中获取文档树。然后,将所有列标题收集到一个列表中。
Example
from bs4 import BeautifulSoup
soup = BeautifulSoup(markup, "html.parser")
tbltag = soup.find('table')
headers = []
headings = tbltag.find_all('th')
for h in headings: headers.append(h.string)
然后获取标题行之后的具有 class='data' 属性的数据行标签。将一个词典对象(以列标题为键,每个单元格中的相应值为值)形成,并将其附加到一个字典对象列表中。
rows = tbltag.find_all_next('tr', {'class':'data'})
trows=[]
for i in rows:
row = {}
data = i.find_all('td')
n=0
for j in data:
row[headers[n]] = j.string
n+=1
trows.append(row)
trows 中收集了一个字典对象列表。然后,你可以将此列表用于其他各种目的,例如存储在 SQL 表格中、以 JSON 或 pandas 数据框对象的形式保存。
以下是完整代码 −
markup = """
<html>
<body>
<p>Beautiful Soup - Parse Table</p>
<table>
<tr>
<th>Name</th>
<th>Age</th>
<th>Marks</th>
</tr>
<tr class='data'>
<td>Ravi</td>
<td>23</td>
<td>67</td>
</tr>
<tr class='data'>
<td>Anil</td>
<td>27</td>
<td>84</td>
</tr>
</table>
</body>
</html>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(markup, "html.parser")
tbltag = soup.find('table')
headers = []
headings = tbltag.find_all('th')
for h in headings: headers.append(h.string)
print (headers)
rows = tbltag.find_all_next('tr', {'class':'data'})
trows=[]
for i in rows:
row = {}
data = i.find_all('td')
n=0
for j in data:
row[headers[n]] = j.string
n+=1
trows.append(row)
print (trows)