PythonでWebスクレイピングを行う際、多くのエンジニアがBeautiful Soupを利用してHTMLからテキストを抽出します。
しかし、単純にテキストを取得するだけでは、HTMLタグの間に含まれる不必要な改行や連続した空白がそのまま残ってしまうことがよくあります。
データのクレンジングは、その後の自然言語処理やデータ分析の精度を左右する重要なプロセスです。
本記事では、Beautiful Soupのget_text()メソッドを活用して、効率的に空白や改行を除去する方法を具体的に解説します。
最新のPython環境においても汎用的に使えるテクニックをマスターして、きれいなデータを取得しましょう。
Beautiful Soupのget_text()メソッドの基本
Beautiful Soupにおいて、HTML要素からテキストのみを取り出す最も一般的な方法がget_text()メソッドです。
このメソッドは、指定したタグの中にあるすべての文字列を連結して返してくれます。
まずは、何もオプションを指定しない場合の挙動を確認してみましょう。
from bs4 import BeautifulSoup
# サンプルHTML
html_content = """
<div class="content">
<h1> 最新の Python </h1>
<p>スクレイピングで<br>データを取得します。</p>
</div>
"""
soup = BeautifulSoup(html_content, "html.parser")
text = soup.get_text()
print(f"取得結果:\n'{text}'")
取得結果:
'
最新の Python
スクレイピングでデータを取得します。
'
実行結果を見ると、HTMLのインデントに使われていた改行や、タグの間にあった余分な空白がそのまま保持されていることがわかります。
このままの状態でデータベースに保存したり解析に回したりすると、予期せぬエラーやノイズの原因になります。
strip=True引数による前後の空白除去
get_text()には、取得したテキストの前後にある空白を削除するための便利な引数が用意されています。
それがstrip=Trueというオプションです。
この引数を指定することで、各テキストノードの前後に存在する空白文字や改行を自動的にカットしてくれます。
# strip引数を使用した場合
clean_text = soup.get_text(strip=True)
print(f"strip=Trueの結果:\n'{clean_text}'")
strip=Trueの結果:
'最新の Pythonスクレイピングでデータを取得します。'
結果を確認すると、テキストの前後にあった空白や改行が消えていることが確認できます。
ただし、この方法だけでは「Python」と「スクレイピング」の間にあった改行も消えてしまい、文章が繋がってしまう点に注意が必要です。
単語同士がくっついてしまうのを防ぎたい場合は、次のセクションで紹介する引数を併用します。
separator引数でテキストを適切に区切る
複数のタグにまたがるテキストを取得する際、タグの境界に特定の文字列を挿入できるのがseparator引数です。
デフォルトでは空文字列が指定されているためテキストが連結されますが、ここに空白や読点などを指定できます。
実務で最も推奨されるのは、separatorとstrip=Trueを組み合わせる手法です。
# セパレーターに半角スペースを指定
separated_text = soup.get_text(separator=" ", strip=True)
print(f"separator指定の結果:\n'{separated_text}'")
separator指定の結果:
'最新の Python スクレイピングで データを取得します。'
このように設定することで、タグの区切りにスペースが入り、かつ各要素の余分な空白も取り除かれた理想的な状態になります。
CSV形式で出力したい場合はカンマを指定するなど、用途に合わせて柔軟に変更可能です。
正規表現(reモジュール)を用いた高度な空白除去
get_text()の機能だけでは、テキストの中間に含まれる「連続した空白」や「タブ文字」を完全に制御できない場合があります。
より厳密にデータを整形したい場合は、Pythonの標準ライブラリであるre(正規表現)モジュールを併用しましょう。
例えば、2つ以上続く空白を1つのスペースに置換したり、すべての改行を削除したりする処理が可能です。
import re
raw_text = soup.get_text(separator=" ", strip=True)
# 連続する空白(改行やタブ含む)を1つのスペースに置換
final_text = re.sub(r'\s+', ' ', raw_text)
print(f"正規表現適用後:\n'{final_text}'")
正規表現適用後:
'最新の Python スクレイピングで データを取得します。'
この正規表現\s+は、空白、タブ、改行の1回以上の繰り返しにマッチします。
スクレイピングしたデータの品質を一段階引き上げるためには、この正規表現による後処理が非常に有効です。
リスト内包表記を活用した特定要素のクレンジング
ページ全体ではなく、特定のリストアイテムやテーブルのセルから個別にテキストを抽出したい場面も多いでしょう。
その場合は、find_all()で取得した要素に対してリスト内包表記の中でstrip()を適用するのが効率的です。
html_list = """
<ul>
<li> Python 3.12 </li>
<li> Beautiful Soup 4 </li>
<li> Pandas </li>
</ul>
"""
soup_list = BeautifulSoup(html_list, "html.parser")
# 各liタグから空白を除去してリスト化
items = [li.get_text(strip=True) for li in soup_list.find_all('li')]
print(items)
['Python 3.12', 'Beautiful Soup 4', 'Pandas']
この手法を使えば、余分な空白を含まない綺麗なリストデータを一行のコードで生成できます。
大量のデータを処理する際は、ループ処理の中で個別にstrip()をかけるよりも可読性が高まります。
各手法の比較まとめ
これまでに紹介した手法の特徴を整理しました。
目的に応じて最適なアプローチを選択してください。
| 手法 | メリット | デメリット |
|---|---|---|
get_text() | 最もシンプルで記述が楽 | 不要な改行や空白が残りやすい |
strip=True | 前後の空白を簡単に消せる | タグ間の単語が繋がることがある |
separator=" " | 単語の結合を防ぎ可読性が向上 | 複雑な空白パターンには対応不可 |
| 正規表現併用 | 完璧なデータクレンジングが可能 | コードが少し複雑になり処理負荷が増す |
まとめ
Beautiful Soupのget_text()は非常に強力なメソッドですが、そのまま使うだけでは不十分なケースが多々あります。
基本的には、get_text(separator=' ', strip=True)をベースとして利用するのが最も効率的です。
さらに高度な整形が必要な場合には、Python標準のstrip()メソッドやre.sub()による正規表現を組み合わせましょう。
2026年現在、AIによるデータ解析の需要はますます高まっており、入力データの質を整えるスクレイピング技術の重要性は揺るぎません。
今回紹介したテクニックを活用して、ノイズのない綺麗なテキストデータを取得できるエンジニアを目指しましょう。
