正しいネスト順序で開いているタグを閉じて、ユーザーが送信した HTML をサニタイズする必要があります。これを行うためのアルゴリズムまたは Python コードを探していましたが、PHP などの中途半端な実装以外は何も見つかりませんでした。
たとえば、次のようなもの
<p>
<ul>
<li>Foo
になる
<p>
<ul>
<li>Foo</li>
</ul>
</p>
どんな助けでも大歓迎です:)
BeautifulSoup を使用:
from BeautifulSoup import BeautifulSoup
html = "<p><ul><li>Foo"
soup = BeautifulSoup(html)
print soup.prettify()
あなたを取得します
<p>
<ul>
<li>
Foo
</li>
</ul>
</p>
私の知る限り、<li></li> タグを Foo とは別の行に配置することは制御できません。
Tidyを使用:
import tidy
html = "<p><ul><li>Foo"
print tidy.parseString(html, show_body_only=True)
あなたを取得します
<ul>
<li>Foo</li>
</ul>
残念ながら、この例で <p> タグを保持する方法はわかりません。Tidy はそれを閉じられていない段落ではなく、空の段落として解釈します。
print tidy.parseString(html, show_body_only=True, drop_empty_paras=False)
として出てくる
<p></p>
<ul>
<li>Foo</li>
</ul>
もちろん、最終的には、例の <p> タグは冗長であるため、なくても問題ない場合があります。
最後に、Tidy はインデントも実行できます。
print tidy.parseString(html, show_body_only=True, indent=True)
になる
<ul>
<li>Foo
</li>
</ul>
これらにはすべて浮き沈みがありますが、そのうちの 1 つが十分に近いことを願っています。
今、lxml と pyquery がうまく機能しない html を取得しました。html にいくつかのエラーがあるようです。Tidy を Windows にインストールするのは簡単ではないため、 を選択しますBeautifulSoup
。しかし、私はそれを見つけました:
from BeautifulSoup import BeautifulSoup
import lxml.html
soup = BeautifulSoup(page)
h = lxml.html(soup.prettify())
と同じように振る舞うh = lxml.html(page)
私の問題を実際に解決するのは ですsoup = BeautifulSoup(page, 'html5lib')
。
最初にインストールhtml5lib
してから、 でパーサーとして使用できますBeautifulSoup
。
html5lib
パーサーは他のパーサーよりもはるかに優れているようです。
これが誰かを助けることを願っています。