見出し画像

Beautiful Soup で prettify() するときにタグ前後の改行をさせないようにする

このような HTML があったとして、それを Beautiful Soup のオブジェクトとして読み込み、それを単純にそのまま `prettify()` で書き出すとします。

from bs4 import BeautifulSoup

s = '''
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>soup test</title>
  </head>
  <body>
	<p>これは Beautiful Soup の<strong>テスト</strong>です。</p>
	<p>これは<ruby>羹<rp>(</rp><rt>スープ</rt><rp>)</rp></ruby>です。</p>
  </body>
</html>
'''
soup = BeautifulSoup(s, 'lxml')
print(soup.prettify())

すると「インライン要素」(MDN 表記では 記述コンテンツ, Phrasing content https://developer.mozilla.org/en-US/docs/Web/HTML/Content_categories#phrasing_content )であっても、以下のようにタグの前後に改行が追加されます。

 <body>
  <p>
   これは Beautiful Soup の
   <strong>
    テスト
   </strong>
   です。
  </p>
  <p>
   これは
   <ruby>
    羹
    <rp>
     (
    </rp>
    <rt>
     スープ
    </rt>
    <rp>
     )
    </rp>
   </ruby>
   です。
  </p>
 </body>
</html>

ブラウザの仕様にもよるところがありますが、ブロック(サンプルで言うところの <p> タグ)内の改行は半角スペース 1 つとして扱われます。この半角スペースは、大抵意図しない不要なものになってしまい、場合によってはデザインが崩れてしまうかもしれません。
このように「タグの前後を改行させたくない場合どうすればよいか」が今回の課題です。

Beautiful Soup で prettify() するときにタグの前後に改行させないようにする方法

ということで、そのやりかたです。

Beautiful Soup のオブジェクトを作成するときに preserve_whitespace_tags というオプションを指定すれば OK です。指定内容は HTML タグを辞書の配列で「その要素内のタグの前後は改行させない」というタグを指定します。
上のサンプルとしては <p> タグを指定してあげれば、課題を達成できます。

preserve_whitespace_tags = {'textarea', 'p'}
soup = BeautifulSoup(s, 'lxml',
	   preserve_whitespace_tags=preserve_whitespace_tags)
print(soup.prettify())

結果は以下の通りです。 `prettify()` の結果は `<p>` タグ内におけるタグの前後を改行しないようになりました。

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8"/>
  <title>
   soup test
  </title>
 </head>
 <body>
  <p>これは Beautiful Soup の<strong>テスト</strong>です。</p>
  <p>これは<ruby>羹<rp>(</rp><rt>スープ</rt><rp>)</rp></ruby>です。</p>
 </body>
</html>

最後に

アイキャッチは Python などと特に関係のない蚊取り線香です。

老後、奥さんと世界一周のための費用にします。