PythonでWebスクレイピングを行う際、BeautifulSoupライブラリは非常に強力なツールとなります。
HTML要素からテキスト情報を抽出する場面で、多くの開発者が「.string」と「get_text()」のどちらを使うべきか迷うことがあります。
一見すると同じようにテキストを返しているように見えますが、内部的な挙動や抽出できる範囲には大きな違いが存在します。
この記事では、2026年現在の最新の仕様を踏まえ、これら二つの機能の差異を整理して紹介します。
それぞれの特性を理解することで、スクレイピング時の予期せぬエラーやデータ取得漏れを防ぐことができるようになります。
.string属性の特徴と基本的な使い方
.stringは、指定したタグの中に含まれる文字列を直接参照するための属性です。
この属性の最大の特徴は、タグの中に「単一のテキストノードのみ」が存在する場合に、そのテキストを返すという点にあります。
もし対象のタグの中に他の子タグが含まれていたり、複数のテキストノードが混在していたりすると、.stringはNoneを返すという性質を持っています。
これは、BeautifulSoupが「どのテキストを返すべきか判断できない」状態になるためです。
まずは、.stringが正常に動作する例を確認してみましょう。
from bs4 import BeautifulSoup
# 単一のテキストを持つHTML
html = "<p>こんにちは、Pythonです。</p>"
soup = BeautifulSoup(html, 'html.parser')
# .stringを使ってテキストを取得
text = soup.p.string
print(f"取得結果: {text}")
取得結果: こんにちは、Pythonです。
このように、タグの直下にテキストのみが存在する場合は、期待通りに文字列が取得できます。
しかし、次に示すような複雑な構造では注意が必要です。
# 子タグが含まれるHTML
html_nested = "<div>親要素のテキスト<span>子要素のテキスト</span></div>"
soup_nested = BeautifulSoup(html_nested, 'html.parser')
# .stringで取得を試みる
print(f"ネストされた構造の結果: {soup_nested.div.string}")
ネストされた構造の結果: None
上記の例では、<div>タグの中にテキストと<span>タグが混在しているため、結果がNoneになってしまいます。
get_text()メソッドの特徴と柔軟性
一方で、get_text()はタグ内に含まれるすべてのテキストを再帰的に取得するメソッドです。
対象のタグだけでなく、その配下にあるすべての子孫要素に含まれるテキストを結合して抽出します。
スクレイピングの実務においては、特定のタグ配下の文章を丸ごと取得したいケースが多いため、こちらの方が頻繁に利用されます。
先ほどのネストされたHTML構造に対してget_text()を使用してみましょう。
# get_text()を使用してテキストを取得
print(f"get_textの結果: {soup_nested.div.get_text()}")
get_textの結果: 親要素のテキスト子要素のテキスト
このように、get_text()はタグの構造を無視して中身の文字列をすべて繋げて返してくれます。
また、get_text()は引数を指定することで、テキスト同士の区切り文字を指定することも可能です。
# セパレーターを指定して取得
print(f"セパレーターあり: {soup_nested.div.get_text(separator=' / ')}")
セパレーターあり: 親要素のテキスト / 子要素のテキスト
この機能を使うことで、データの整形が非常に容易になります。
.stringとget_text()の決定的な違いを比較
これら二つの手法の違いを、主要な観点から整理しました。
| 比較項目 | .string属性 | get_text()メソッド |
|---|---|---|
| 取得範囲 | 直下の単一テキストのみ | 子孫要素を含むすべてのテキスト |
| 複数タグ混在時 | Noneを返す | 結合してすべてのテキストを返す |
| 戻り値の型 | NavigableString(またはNone) | str(通常の文字列型) |
| 主な用途 | 特定のタグが持つ値を厳密に取得 | ページ内の文章をまとめて抽出 |
戻り値の型における違い
一見どちらも文字列を返しているように見えますが、戻り値の型には重要な違いがあります。
.stringが返すのはBeautifulSoup独自のNavigableStringオブジェクトです。
これに対して、get_text()が返すのはPython標準のstr型です。
NavigableStringはメモリ上にDOMツリー全体の参照を保持し続けることがあるため、大量のデータを処理する際はメモリ消費量に注意が必要です。
None判定の重要性
プログラムの堅牢性を高めるためには、.stringのNone判定を忘れてはいけません。
スクレイピング対象のサイト構造が少しでも変わると、昨日まで取得できていたデータが急にNoneになり、後続の処理でエラーを吐く可能性があります。
確実性を求めるのであれば、データが存在しない可能性を考慮したコーディングが求められます。
どちらを使うべきか?シーン別の選定基準
基本的には、用途に応じて以下のように使い分けるのがベストプラクティスです。
.stringを使うべきケース
- 特定のタグ(
<span>価格</span>など)の値をピンポイントで取得したい場合 - タグの中に他の要素が入り込んでいないことを保証(バリデーション)したい場合
- タグ自体がテキストノードと1対1で対応していることが明確な場合
get_text()を使うべきケース
- 記事の本文やコメント欄など、複数のタグで構成された文章を一度に取得したい場合
- HTML構造が複雑、あるいは動的に変化する可能性がある場合
- 取得したテキストを特定の文字で区切ってリスト化したい場合
現代のWebサイトは広告やアイコンなどのタグが本文に混じることが多いため、実務の多くではget_text()が推奨されます。
まとめ
BeautifulSoupにおける.stringとget_text()は、一見似て非なるものです。
.stringは厳密な抽出に向いており、構造が変わるとNoneを返す繊細なツールです。
対してget_text()は、配下のテキストを漏れなく拾い上げる、汎用性の高い強力なメソッドです。
スクレイピングを行う際は、まず取得したい要素のHTML構造をブラウザのデベロッパーツールで詳しく観察してください。
その上で、データの「正確性」が必要なら.stringを、データの「網羅性」が必要ならget_text()を選択するようにしましょう。
これらの特性を正しく理解し使い分けることで、より堅牢でメンテナンス性の高いスクレイピングコードを作成できるようになります。
