BeatifulSoup3 ではそんなことはなかったようですが、
BeatifulSoup4 だと、html タグ、body タグがない、html を解析すると、
足りないタグを補完してくれる動作をします。

BeautifulSoup("<a><b /></a>")
# <html><head></head><body><a><b></b></a></body></html>

この動作で嬉しい時もあると思いますが、
嬉しくない場合もあり、余分なタグを除去する方法を調べてみました。


参考


除去する方法

1. html の parser を変更する。

python の 標準 の html.parser使うようにすると、
html タグ、 body タグは付与されなくなります。

BeautifulSoup("<a></p>", "html.parser")
# <a></a>

2. parser は、変更せず、soup.body.hidden = True とする。

以下で、body タグを非表示にして、
非表示にした、body を テキストに書き出すことで中身が取り出せます。

soup = BeautifulSoup(html)
soup.body.hidden = True
return str(soup.body)

上記、実装でうまく動いていると思ったのですが、
後日、ログを確認したところ以下、WARNING が出力されていました。

The code that caused this warning is on line 170 of the file /usr/local/lib/python2.7/site-packages/django/core/handlers/wsgi.py. To get rid of this warning, change code that looks like this:

BeautifulSoup([your markup])
to this:
BeautifulSoup([your markup], "html5lib")
markup_type=markup_type))

Beautiful Soup 4.x では parser を明示指定しよう - AWS / PHP / Python ちょいメモ
記載がありますが、
parser を明示的に指定しないと出力される WARNING なので以下の通り、parser を指定しました。

soup = BeautifulSoup(html, "html5lib")
soup.body.hidden = True
return str(soup.body)


どちらを採用したか

parser を変更すると、タグが間違っていた場合の補完の方法が変わります。
今回は、BeautifulSoup のデフォルト parser の補完の仕方がよかったので、
soup.body.hidden = Trueしてタグ除去を行いました。

以上です。

コメント