如何使用Python为现有HTML添加一致的空格?

时间:2010-02-17 09:08:19

标签: python html whitespace html5lib

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

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

首先,有人知道只有html5lib这是否可行? (不幸的是,他们的文档看起来有点稀疏。)如果没有,你会建议使用什么工具?我见过有人推荐HTML Tidy,但我不确定它是否可以配置为只改变空格。 (除非插入空格,否则它会执行任何操作,如果它通过格式良好的HTML开始?)

3 个答案:

答案 0 :(得分:2)

算法

  1. 将html解析为某种表示
  2. 将表示序列化回html
  3. 示例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>
    

答案 1 :(得分: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>

为什么我要迭代树的子项,而不是直接在toprettyxml()上调用dom_tree?我正在处理的一些HTML实际上是HTML片段,所以它缺少<head><body>标签。为了解决这个问题,我使用了parseFragment()方法,这意味着我得到了一个DocumentFragment(而不是Document)。不幸的是,它没有writexml()方法(toprettyxml()调用),因此我遍历了具有该方法的子节点。

答案 2 :(得分:1)

如果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()方法。