python - 在python中将嵌套的html表转换为嵌套字典?
问题描述
我正在编写一个应用程序将从网站接收的 html 表字符串数据(通过调用 RESR API)转换为字典格式。问题是HTML表格字符串的格式是嵌套的HTML表格格式。在互联网上搜索了一段时间后,我找不到这种情况的解决方案。尽管将 json 转换为 html 有很多解决方案。我的 HTML 表格字符串输入是:
<table>
<tr>
<td>
<table>
<tr>
<th>sku</th>
<td>
<table>
<tr>
<th>capacity</th>
<td>1</td>
</tr>
<tr>
<th>name</th>
<td>Developer</td>
</tr>
</table>
</td>
</tr>
<tr>
<th>tags</th>
<td></td>
</tr>
<tr>
<th>properties</th>
<td>
<table>
<tr>
<th>gatewayRegionalUrl</th>
<td>https:test</td>
</tr>
<tr>
<th>createdAtUtc</th>
<td>2019-03-18T08:11:21.0001331Z</td>
</tr>
<tr>
<th>virtualNetworkType</th>
<td>None</td>
</tr>
<tr>
<th>additionalLocations</th>
<td>None</td>
</tr>
<tr>
<th>customProperties</th>
<td>
<table>
<tr>
<th>Protocols.Server.Http2</th>
<td>False</td>
</tr>
</table>
</td>
</tr>
<tr>
<th>certificates</th>
<td>None</td>
</tr>
</table>
</td>
</tr>
<tr>
<th>etag</th>
<td>AAAAAAFy3Vo=</td>
</tr>
<tr>
<th>type</th>
<td>test/service</td>
</tr>
<tr>
<th>id</th>
<td>/test</td>
</tr>
</table>
</td>
</tr>
</table>
我使用 python 库 BeautifulSoup 处理 HTML 字符串,使用方法 find_all() 来查找所有表标记并提取键和值的 th 和 td 标记,但问题是如何处理另一个表标记中的子表标记。我曾考虑使用 BeautifulSoup 库的递归函数来解决这个问题,有人建议我怎么做吗?
import json
from bs4 import BeautifulSoup
str_html = "<table><tr><td><table><tr><th>sku</th><td><table><tr><th>capacity</th><td>1</td></tr><tr><th>name</th><td>Developer</td></tr></table></td></tr><tr><th>tags</th><td></td></tr><tr><th>properties</th><td><table><tr><th>gatewayRegionalUrl</th><td>https:test/td></tr><tr><th>createdAtUtc</th><td>2019-03-18T08:11:21.0001331Z</td></tr><tr><th>virtualNetworkType</th><td>None</td></tr><tr><th>additionalLocations</th><td>None</td></tr><tr><th>customProperties</th><td><table><tr><th>Protocols.Server.Http2</th><td>False</td></tr></table></td></tr><tr><th>certificates</th><td>None</td></tr></table></td></tr><tr><th>etag</th><td>AAAAAAFy3Vo=</td></tr><tr><th>type</th><td>test/service</td></tr><tr><th>id</th><td>test</td></tr></table></td></tr></table>"
print(type(str_html))
for table in soup.find_all('table'):
keys = [th.get_text(strip=True)for th in table.find_all('th')]
values = [td.get_text("strip=True) for td in table.find_all('td')]
d = dict(zip(keys, values))
print(d)
我的期望结果输出是:
{
"etag": "AAAAAAFy3Vo=",
"id": "test",
"properties": {
"additionalLocations": null,
"certificates": null,
"createdAtUtc": "2019-03-18T08:11:21.0001331Z",
"customProperties": {
"Protocols.Server.Http2": "False",
},
"gatewayRegionalUrl": "https:test",
"virtualNetworkType": "None"
},
"sku": {
"capacity": 1,
"name": "Developer"
},
"tags": {},
"type": "test/service"
}
解决方案
您可以使用 lxml 库来解析 html 文档,如下所示:
doc = lxml.html.fromstring(page_html)
之后,您可以像这样提取第th块:
ths = doc.xpath('//th'):
并在每个块中迭代以以相同的方式提取对 (key,value)。最后,将数据转换为json。
推荐阅读
- excel - VBA 帮助 - 如果一个单元格包含特定值并且另一个单元格有日期?比另一个单元格 - 删除整行
- java - 为什么调用 JFrame 时我的 JPanel 不显示?
- python - 将 UTF-16 字符串解码为 ASCII
- excel - 使用宏导入多个 Txt 文件
- r - 评估一个变量,使其可以出现在 R markdown 的代码块中
- javascript - 用于搜索唯一对象并从值中提取总和的 JavaScript
- count - 使用 INNER JOIN 进行计数和求和
- three.js - Three.js 和应用纹理
- python - 当我使用切片语法`mylist[:] = [mylist, mylist, ...]` 将带有自引用的列表分配给列表副本时会发生什么?
- android - 如何从textview获取drawable