假设我有以下 HTML 表格:
<table>
<tr>
<th>Name</th>
<th>Age</th>
<th>License</th>
<th>Amount</th>
</tr>
<tr>
<td>John</td>
<td>28</td>
<td>Y</td>
<td>12.30</td>
</tr>
<tr>
<td>Kevin</td>
<td>25</td>
<td>Y</td>
<td>22.30</td>
</tr>
<tr>
<td>Smith</td>
<td>38</td>
<td>Y</td>
<td>52.20</td>
</tr>
<tr>
<td>Stewart</td>
<td>21</td>
<td>N</td>
<td>3.80</td>
</tr>
</table>
我想将此表转换为 JSON,可能采用以下格式:
data= [
{
Name: 'John',
Age: 28,
License: 'Y',
Amount: 12.30
},
{
Name: 'Kevin',
Age: 25,
License: 'Y',
Amount: 22.30
},
{
Name: 'Smith',
Age: 38,
License: 'Y',
Amount: 52.20
},
{
Name: 'Stewart',
Age: 21,
License: 'N',
Amount: 3.80
}
];
我见过另一个执行上述操作的示例,我发现它 here 。 然而,鉴于这个答案,有一些事情我无法完成。它们是:
- 表格上仅限两行。如果我添加额外的行,则会收到错误:
print(json.dumps(OrderedDict(table_data))) ValueError: too many values to unpack (expected 2)
- 不考虑表格的标题行。
这是我到目前为止的代码:
html_data = """
<table>
<tr>
<th>Name</th>
<th>Age</th>
<th>License</th>
<th>Amount</th>
</tr>
<tr>
<td>John</td>
<td>28</td>
<td>Y</td>
<td>12.30</td>
</tr>
<tr>
<td>Kevin</td>
<td>25</td>
<td>Y</td>
<td>22.30</td>
</tr>
<tr>
<td>Smith</td>
<td>38</td>
<td>Y</td>
<td>52.20</td>
</tr>
<tr>
<td>Stewart</td>
<td>21</td>
<td>N</td>
<td>3.80</td>
</tr>
</table>
"""
from bs4 import BeautifulSoup
from collections import OrderedDict
import json
table_data = [[cell.text for cell in row("td")]
for row in BeautifulSoup(html_data, features="lxml")("tr")]
print(json.dumps(OrderedDict(table_data)))
但我收到以下错误:
print(json.dumps(OrderedDict(table_data))) ValueError: need more than 0 values to unpack
编辑 如果 HTML 中只有一张表,下面的答案将非常有效。如果有两张表怎么办?例如:
<html>
<body>
<h1>My Heading</h1>
<p>Hello world</p>
<table>
<tr>
<th>Name</th>
<th>Age</th>
<th>License</th>
<th>Amount</th>
</tr>
<tr>
<td>John</td>
<td>28</td>
<td>Y</td>
<td>12.30</td>
</tr>
<tr>
<td>Kevin</td>
<td>25</td>
<td>Y</td>
<td>22.30</td>
</tr>
<tr>
<td>Smith</td>
<td>38</td>
<td>Y</td>
<td>52.20</td>
</tr>
<tr>
<td>Stewart</td>
<td>21</td>
<td>N</td>
<td>3.80</td>
</tr>
</table>
<table>
<tr>
<th>Name</th>
<th>Age</th>
<th>License</th>
<th>Amount</th>
</tr>
<tr>
<td>Rich</td>
<td>28</td>
<td>Y</td>
<td>12.30</td>
</tr>
<tr>
<td>Kevin</td>
<td>25</td>
<td>Y</td>
<td>22.30</td>
</tr>
<tr>
<td>Smith</td>
<td>38</td>
<td>Y</td>
<td>52.20</td>
</tr>
<tr>
<td>Stewart</td>
<td>21</td>
<td>N</td>
<td>3.80</td>
</tr>
</table>
</body>
</html>
如果我将其插入下面的代码中,则只有第一个表显示为 JSON 输出。
最佳答案
您可以使用soup.find_all
:
from bs4 import BeautifulSoup as soup
s = soup(html, 'html.parser').table
h, [_, *d] = [i.text for i in s.tr.find_all('th')], [[i.text for i in b.find_all('td')] for b in s.find_all('tr')]
result = [dict(zip(h, i)) for i in d]
输出:
[{'Name': 'John', 'Age': '28', 'License': 'Y', 'Amount': '12.30'}, {'Name': 'Kevin', 'Age': '25', 'License': 'Y', 'Amount': '22.30'}, {'Name': 'Smith', 'Age': '38', 'License': 'Y', 'Amount': '52.20'}, {'Name': 'Stewart', 'Age': '21', 'License': 'N', 'Amount': '3.80'}]
关于python - 将带有标题的 HTML 表转换为 Json - Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59965892/