Beautiful Soup 4.4.0 で extract() を使うとDOM treeが壊れる?
Python で Beautiful Soup 4.4.0 を使った時に遭遇した問題。stackoverflow でも取り上げられていて、取り敢えずは 4.3.2 に戻すことで対処しました。
環境
問題点
次のようなコードで、html中からscriptタグを除去していたところ 4.0 の環境でおかしな動作が起きた。
soup = BeautifulSoup(page_html, 'lxml') [s.extract() for s in soup('script')]
この処理の後、soup('body') の結果が None になってしまうという現象が発生。また、[s.extract() for s in soup('script')] を何度実行しても消せないscriptタグが出たりと。いずれも4.3.2では、起きてなかった問題でした。
対策
前述の stackoverflowのエントリー を見つけて読んだ所、 extract() 後に 二重改行がはいることでおかしくなるとの回答がある。
解決方法として 1. str(soup) を再度BeautifulSoupでパースする 2. html5lib パーサーを使う が提案されていた。また別の回答としては 4.3.2 だと大丈夫ともある。
僕の環境の場合、4.4.0必須ではなかったのと pip で管理していたのでバージョン固定が簡単にできるということで、4.3.2 固定にして使うことにした。
# pip install beautifulsoup4==4.3.2
その他
Beautiful Soup 4.4.0 は 2015年7月にリリースされているので、次のバージョンアップなどで対策されるのかな?
公式グループでも同じような問題があがっていたけど、誰も回答していないので、少し対応は先になるのかもしれない。
もう少し経験値があがったらコード読んでみようと思う。