【问题标题】:How can I add consistent whitespace to existing HTML using Python?如何使用 Python 向现有 HTML 添加一致的空格?
【发布时间】:2011-01-17 18:36:08
【问题描述】:

我刚开始在一个网站上工作,该网站的所有页面都在一行中,这对于阅读和使用来说真的很痛苦。我正在寻找一种工具(最好是 Python 库),它将接受 HTML 输入并返回相同的 HTML 不变,除了添加换行符和适当的缩进。 (所有标签、标记和内容都应该保持不变。)

该库不必处理格式错误的 HTML;我首先通过html5lib 传递HTML,因此它将获得格式良好的HTML。但是,如上所述,我宁愿它不改变任何实际标记本身;我信任 html5lib,宁愿让它处理正确性方面。

首先,有谁知道这是否可以仅使用 html5lib? (不幸的是,他们的文档似乎有点稀疏。)如果没有,你会建议什么工具?我见过有人推荐 HTML Tidy,但我不确定它是否可以配置为只更改空格。 (如果以格式良好的 HTML 开头,除了插入空格之外,它会做任何事情吗?)

【问题讨论】:

  • ...哇,该文档是AWFUL...
  • 是的,除了介绍页面,阅读代码似乎是唯一的选择……如果我擅长编写文档,我会自愿参加。拍摄,我可能仍然是志愿者,因为我很确定多吃点会有所改善。

标签: python html whitespace html5lib


【解决方案1】:

算法

  1. 将 html 解析为某种表示形式
  2. 将表示序列化回 html

示例html5lib parser with BeautifulSoup tree builder

#!/usr/bin/env python
from html5lib import HTMLParser, treebuilders

parser = HTMLParser(tree=treebuilders.getTreeBuilder("beautifulsoup"))

c = """<HTML><HEAD><TITLE>Title</TITLE></HEAD><BODY>...... </BODY></HTML>"""

soup = parser.parse(c)
print soup.prettify()

输出:

<html>
 <head>
  <title>
   Title
  </title>
 </head>
 <body>
  ......
 </body>
</html>

【讨论】:

    【解决方案2】:

    我选择 J.F. Sebastian 的答案是因为我认为它是最简单的,因此也是最好的,但我正在为不想安装 Beautiful Soup 的任何人添加另一个解决方案。 (此外,Beautiful Soup 树构建器将是 deprecated in html5lib 1.0。)这个解决方案感谢 Amarghosh 的提示;我只是充实了一点。查看html5lib,我意识到它会原生输出一个minidom对象,这意味着我可以使用他的toprettyxml()的建议。这是我想出的:

    from html5lib import HTMLParser, treebuilders
    from cStringIO import StringIO
    
    def tidy_html(text):
      """Returns a well-formatted version of input HTML."""
    
      p = HTMLParser(tree=treebuilders.getTreeBuilder("dom"))
      dom_tree = p.parseFragment(text)
    
      # using cStringIO for fast string concatenation
      pretty_HTML = StringIO()
    
      node = dom_tree.firstChild
      while node:
        node_contents = node.toprettyxml(indent='  ')
        pretty_HTML.write(node_contents)
        node = node.nextSibling
    
      output = pretty_HTML.getvalue()
      pretty_HTML.close()
      return output
    

    还有一个例子:

    >>> text = """<b><i>bold, italic</b></i><div>a div</div>"""
    >>> tidy_html(text)
    <b>
      <i>
        bold, italic
      </i>
    </b>
    <div>
      a div
    </div>
    

    为什么我要遍历树的子节点,而不是直接在 dom_tree 上调用 toprettyxml()?我正在处理的一些 HTML 实际上是 HTML 片段,所以它缺少 &lt;head&gt;&lt;body&gt; 标记。为了处理这个问题,我使用了parseFragment() 方法,这意味着我得到了一个 DocumentFragment 作为回报(而不是一个 Document)。不幸的是,它没有writexml() 方法(toprettyxml() 调用),所以我遍历子节点,它们确实有方法。

    【讨论】:

      【解决方案3】:

      如果 html 确实是格式良好的 xml,则可以使用 DOM 解析器。

      from xml.dom.minidom import parse, parseString
      
      #if you have html string in a variable
      html = parseString(theHtmlString)
      
      #or parse the html file
      html = parse(htmlFileName)
      
      print html.toprettyxml()
      

      toprettyxml() 方法允许指定缩进、换行符和输出的编码。您可能还想查看writexml() 方法。

      【讨论】:

      • 多亏了你,在看到上面 J.F. Sebastian 的更好示例之前,我整理了一个非常可行的解决方案。 (我将其作为另一个答案提交,以便其他不想安装 Beautiful Soup 的人有另一种选择。)感谢您的领导!
      猜你喜欢
      • 1970-01-01
      • 2017-04-16
      • 2020-12-11
      • 1970-01-01
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      • 2022-09-27
      相关资源
      最近更新 更多