【问题标题】:HTML to JSON with Formatting Python带有格式化 Python 的 HTML 到 JSON
【发布时间】:2020-06-03 20:39:16
【问题描述】:

我在网上看到了几个关于如何将 HTML 内容转换为 JSON 的示例,但我无法得到实际结果。

假设我有以下 html_content:

<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>
    </body>
</html>

如您所见,它包含标题、段落和表格元素。 我正在尝试将上述内容转换为 JSON 并将结果输出到一个单独的文件,格式为 正确。这是我的代码:

import sys
import json
jsonD = json.dumps(html_content, sort_keys=True, indent=4)

sys.stdout=open("output.json","w")
print (jsonD)
sys.stdout.close()

结果是:

"\n<html>\n\t<body>\n\t\t<h1>My Heading</h1>\n\t\t<p>Hello world</p>\n\t\t<table>\n\t\t\t<tr>\n\t\t\t\t<th>Name</th>\n\t\t\t\t<th>Age</th>\n\t\t\t\t<th>License</th>\n\t\t\t\t<th>Amount</th>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td>John</td>\n\t\t\t\t<td>28</td>\n\t\t\t\t<td>Y</td>\n\t\t\t\t<td>12.30</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td>Kevin</td>\n\t\t\t\t<td>25</td>\n\t\t\t\t<td>Y</td>\n\t\t\t\t<td>22.30</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td>Smith</td>\n\t\t\t\t<td>38</td>\n\t\t\t\t<td>Y</td>\n\t\t\t\t<td>52.20</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td>Stewart</td>\n\t\t\t\t<td>21</td>\n\t\t\t\t<td>N</td>\n\t\t\t\t<td>3.80</td>\n\t\t\t</tr>\n\t\t</table>\n\t</body>\n</html>\n"

如您所见,结果没有转义任何返回或制表符,并且使输出看起来像一个长字符串。我该如何纠正这个问题,以便从 JSON 角度正确地格式化输出?

【问题讨论】:

  • 你期待什么输出?
  • 这可能是一个有用的例子:xavierdupre.fr/blog/2013-10-27_nojs.html
  • @ZacharyBlackwood 这个例子我看过,但是如何导入 HTMLtoJSONParser 模块?
  • @AlexW 类似于我放置的输出,但每个元素之间没有“/n”和“/t”。相反,它实际上应该在写入时返回到新行或缩进。
  • @Adam 在那篇博文中,他实际上创建了 HTMLtoJSONParser,这不是他从其他地方导入的东西

标签: python html json


【解决方案1】:

您需要知道您希望 json 输出的外观。如果您希望名称是键,而值是其他所有内容的列表,我会这样做:

from bs4 import BeautifulSoup
import json

html_content = """
<table>
    <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>
<h1> hello world <h1>
<table>
    <tr>
        <td>Jack</td>
        <td>1</td>
    </tr>
    <tr>
        <td>Joe</td>
        <td>2</td>
    </tr>
    <tr>
        <td>Bill</td>
        <td>3</td>
    </tr>
    <tr>
        <td>Sam</td>
        <td>4</td>
    </tr>
</table>
"""

html_content_parsed = [[cell.text for cell in row("td")]
                         for row in BeautifulSoup(html_content,features="html.parser")("tr")]

html_content_dictionary = {element[0]:element[1:] for element in html_content_parsed}

print(json.dumps(html_content_dictionary, indent=4))

如您所见,这会忽略其他非表格元素,并将所有表格放入json中。

您可以在此处试用该程序: https://repl.it/@Mandawi/htmltojson

【讨论】:

  • 谢谢。我在这里看到了相同的响应:stackoverflow.com/a/59968204/3480297 但是当 html 中有多个表或除“表”之外的不同元素时,这不起作用。你知道怎么解决吗?
  • 是的,同样的想法!
  • 如果html_content有多个表怎么办?这只会为我显示第一个表。
  • 我不知道你所说的除表格以外的元素是什么意思。你想把这些元素也放在 json 中吗?如果你不这样做,那么这将简单地忽略它们。如果你这样做了,那么就按照你希望它们在 json 中的样子来解析它们。
  • 对不起,我认为您提到的其他元素可以格式化。但如果有多个表,则 JSON 仅输出第一个表。你可以试试看,看看你是否也会发生同样的情况?
【解决方案2】:

有一个库可以将 html 转换为 json here(完全披露:我是这个库的作者)。该库可以将 HTML 转换为 JSON,并具有仅将 HTML 表格转换为 JSON 的特定功能(您将其提供为 HTML,它会找到所有表格并将其转换为 JSON)。

对于您的特定用例,您可以安装 html-to-json 库(请参阅说明here)然后运行:

import html_to_json

import html_to_json
s = '''<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>
    </body>
</html>'''

html_to_json.convert_tables(s)

正如您在下面的输出中所见,html-to-json 库使用 &lt;th&gt; 元素(如果可用)作为输出 JSON 的键:

[
  [
    {
      "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"
    }
  ]
]

如果您想转换整个 HTML(而不仅仅是表格),可以将 html_to_json.convert_tables(s) 替换为 html_to_json.convert(s)

【讨论】:

    猜你喜欢
    • 2015-06-01
    • 1970-01-01
    • 2020-08-29
    • 2021-07-03
    • 2017-11-08
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多