3

すべての HTML が 1 行にまとめられたページでいっぱいの Web サイトで作業を始めたばかりですが、これを読んだり操作したりするのは本当に面倒です。改行と適切なインデントを追加することを除いて、HTML入力を受け取り、同じHTMLを変更せずに返すツール(できればPythonライブラリ)を探しています。(すべてのタグ、マークアップ、およびコンテンツは変更しないでください。)

ライブラリは不正な HTML を処理する必要はありません。最初にhtml5libを介して HTML を渡しているので、整形式の HTML が得られます。ただし、前述のとおり、実際のマークアップ自体は一切変更しない方がよいでしょう。私は html5lib を信頼しており、正確さの側面を処理させたいと考えています。

まず、html5libだけでこれが可能かどうか知っていますか? (残念ながら、彼らのドキュメントは少しまばらなようです。)そうでない場合、どのツールをお勧めしますか? HTML Tidy を推奨する人もいますが、空白のみを変更するように構成できるかどうかはわかりません。(最初に整形式の HTML が渡された場合、空白を挿入する以外に何かを行うでしょうか?)

4

3 に答える 3

2

JF Sebastian の回答を選択したのは、それが最も単純で最良だと思うからですが、Beautiful Soup をインストールしたくない人のために別のソリューションを追加しています。(また、Beautiful Soup ツリー ビルダーはhtml5lib 1.0 で廃止される予定です。) この解決策は、Amargosh のヒントのおかげです。少しだけ肉付けしました。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()メソッドを使用しました。つまり、(Document ではなく) DocumentFragment を返します。残念ながら、writexml()メソッド (toprettyxml()呼び出す) がないため、メソッドを持つ子ノードを反復処理します。

于 2010-02-17T22:39:05.797 に答える
2

アルゴリズム

  1. HTML を何らかの表現に解析する
  2. 表現を html にシリアライズします

BeautifulSoup ツリー ビルダーを使用した html5lib パーサーの

#!/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>
于 2010-02-17T13:05:33.377 に答える