PythonとSeleniumを組み合わせてウェブスクレイピングやブラウザ自動化を行う際、最も頻繁に行われる操作の一つが「要素内のテキスト取得」です。
画面上に表示されている文字情報を取得するだけであれば簡単に見えますが、実際には対象の要素が隠れていた利、動的に中身が書き換わったりする場合があり、一筋縄ではいかないことも少なくありません。
Seleniumにはテキストを取得するための手段が複数用意されており、それぞれの特性を理解して使い分けることが、安定したスクリプトを作成するための鍵となります。
本記事では、標準的なtextプロパティから、より詳細な制御が可能なget_attributeメソッドまで、2026年現在の最新のベストプラクティスを交えて詳しく解説します。
基本となる text プロパティの使い方
Seleniumで最も一般的に使用されるのは、WebElementオブジェクトのtextプロパティです。
このプロパティは、指定した要素内に含まれるテキストを文字列として返します。
まずは、基本的な要素のテキストを取得するコードを確認してみましょう。
from selenium import webdriver
from selenium.webdriver.common.by import By
# ブラウザの起動(Chromeの例)
driver = webdriver.Chrome()
# テスト対象のページへ移動
driver.get("https://example.com")
# h1タグの要素を取得
element = driver.find_element(By.TAG_NAME, "h1")
# テキストを表示
print(f"取得したテキスト: {element.text}")
driver.quit()
取得したテキスト: Example Domain
このように、.textを使用するだけで直感的に文字情報を取得できることがわかります。
しかし、このtextプロパティには重要な特性があります。
それは、「ユーザーの目に見えているテキストのみを取得する」という点です。
CSSによってdisplay: none;やvisibility: hidden;が設定されている要素のテキストは、このプロパティでは空文字として返されます。
また、余分な空白がトリミングされたり、改行が正規化されたりする挙動も特徴の一つです。
get_attribute(‘textContent’) による詳細なテキスト取得
「画面上には表示されていないが、HTMLソースコード内に存在するテキストを取得したい」というケースでは、get_attribute('textContent')を使用します。
textContentは、DOM(Document Object Model)上のノードに含まれる生のテキストを取得するための属性です。
CSSの影響を受けないため、非表示に設定されている要素であっても確実に内容を抽出することが可能です。
# 非表示要素を含むHTML要素の取得例
hidden_element = driver.find_element(By.ID, "hidden-message")
# textプロパティでは空になる可能性がある
print(f"textプロパティの場合: '{hidden_element.text}'")
# textContent属性なら非表示でも取得可能
raw_text = hidden_element.get_attribute("textContent")
print(f"textContentの場合: '{raw_text}'")
このメソッドは、スクレイピングにおいて「隠しデータ」や「メタ情報」を取得する際に非常に重宝します。
また、textプロパティよりも動作速度がわずかに速いというメリットもあります。
これは、textプロパティがブラウザのレンダリング状態を確認するのに対し、textContentは単純にDOMツリーを参照するだけだからです。
innerText と textContent の違い
get_attributeでは、textContentのほかにinnerTextを指定することもできます。
これら二つは似ていますが、厳密には挙動が異なります。
innerTextは、textプロパティに近い挙動を示し、CSSによるスタイリング(大文字小文字の変換など)を考慮した結果を返します。
一方で、textContentはスクリプト(<script>)やスタイル(<style>)タグの中身まで取得対象に含めることがあります。
純粋にHTML構造の中にある文字列をそのまま抜き出したいのであれば、textContentを選択するのが一般的です。
入力フォームの値を取得する方法 (value 属性)
初心者の方がよく陥る落とし穴として、「inputタグの入力値がtextプロパティで取得できない」という問題があります。
<input>や<textarea>に入力された文字列は、要素のテキストノードではなく、value属性として保持されています。
そのため、これらの値を取得するには必ずget_attribute(‘value’)を使用する必要があります。
# 入力フォームの要素を取得
input_field = driver.find_element(By.NAME, "username")
# テキストを入力
input_field.send_keys("selenium_user")
# 入力された値を取得
current_value = input_field.get_attribute("value")
print(f"フォームの入力値: {current_value}")
この違いを理解していないと、フォームの自動入力テストなどで「値が入っているはずなのに空の文字列が返ってくる」というトラブルに悩まされることになります。
各手法の比較と使い分けのポイント
ここまで紹介した手法を整理するために、比較表を作成しました。
| 取得方法 | 主な用途 | 非表示要素 | 備考 |
|---|---|---|---|
.text | 通常の画面テキスト取得 | 取得不可 | 最も標準的。空白が調整される。 |
.get_attribute("textContent") | 隠しテキストや生データ | 取得可能 | CSSを無視し、全テキストを返す。 |
.get_attribute("value") | フォームの入力値 | – | inputやtextarea要素に必須。 |
基本的には、「ユーザーに見えている情報をテストしたいなら .text」、「HTMLデータを確実に抽出したいなら textContent」と使い分けるのが正解です。
確実にテキストを取得するためのテクニック
動的なウェブサイトでは、ページが表示された直後に要素が存在しても、テキストがまだ読み込まれていない場合があります。
このとき、単純に要素を取得してtextプロパティを呼び出すと、期待した結果が得られないことがあります。
こうした事態を防ぐためには、WebDriverWaitを使用して、要素が特定の状態になるまで待機することが推奨されます。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 要素が表示され、かつテキストが存在するまで最大10秒待機
wait = WebDriverWait(driver, 10)
element = wait.until(EC.visibility_of_element_located((By.ID, "dynamic-content")))
print(f"待機後に取得したテキスト: {element.text}")
この「明示的待機」を組み合わせることで、ネットワークの遅延やJavaScriptの実行待ちによるエラーを大幅に減らすことができます。
また、要素がDOM上に存在していても、透明度が0であったり、他の要素に重なっていたりするとtextが取得できないことがあります。
そのような特殊な状況下でも、textContentであれば値を拾うことができるため、待機処理と属性取得の組み合わせは非常に強力な武器になります。
トラブルシューティング:テキストが取得できない原因と対策
「要素は見つかっているのにテキストが空」という状況に陥った際、チェックすべき項目がいくつかあります。
第一の可能性は、先述した「非表示要素(CSS)」の問題です。
デベロッパーツールで対象要素を確認し、display: none;などが適用されていないか確認してください。
第二の可能性は、iframeの中に要素が存在している場合です。
Seleniumでは、iframe内の要素を操作する前に、driver.switch_to.frame()を使用してコンテキストを切り替える必要があります。
# iframeに切り替え
iframe = driver.find_element(By.ID, "content-frame")
driver.switch_to.frame(iframe)
# iframe内のテキストを取得
print(driver.find_element(By.TAG_NAME, "p").text)
# 元のページに戻る
driver.switch_to.default_content()
第三の可能性は、Shadow DOMの内部にテキストがある場合です。
2026年現在のモダンなウェブサイトではShadow DOMの利用が増えていますが、これは通常のfind_elementではアクセスできません。
Shadow Rootを取得してから、その配下の要素を探索するという手順を踏む必要があります。
実践的なコード例:リスト要素の一括取得
実際の業務では、単一の要素ではなく、検索結果のリストや商品名の一覧などをまとめて取得する場面が多いでしょう。
find_elements(複数形)を使用して、ループ処理でテキストを抽出する効率的な方法を紹介します。
# 商品名一覧を取得(複数要素)
items = driver.find_elements(By.CLASS_NAME, "product-title")
# リストコンプレヘンション(内包表記)でテキストを一括抽出
product_names = [item.text for item in items if item.text]
for name in product_names:
print(f"商品名: {name}")
このように、リスト内包表記の中でif item.textという条件を加えることで、空の要素を除外した綺麗なリストを作成できます。
また、大量の要素からテキストを取得する場合、一つずつ.textにアクセスすると通信オーバーヘッドが発生して処理が遅くなることがあります。
そのような場合は、JavaScriptを実行して一括でテキストを取得するテクニックも検討してください。
# JavaScriptを使用して全アイテムのtextContentを一括取得
script = "return Array.from(document.querySelectorAll('.product-title')).map(el => el.textContent);"
titles = driver.execute_script(script)
print(titles)
この方法は、要素数が数百件を超えるような大規模なページにおいて、実行速度を劇的に改善する効果があります。
まとめ
PythonとSeleniumを用いたテキスト取得には、用途に合わせた最適な選択肢が存在します。
ユーザーが見ているそのままの情報を取得したい場合はtextプロパティが第一選択となります。
一方で、非表示の要素やスクリプトタグ内の情報を扱いたい場合は、get_attribute('textContent')が非常に有効です。
また、入力フォームの値を扱う際には、必ずvalue属性を指定することを忘れないようにしましょう。
これらの使い分けに加えて、WebDriverWaitによる適切な待機処理や、iframe、Shadow DOMへの対応をマスターすることで、堅牢なスクレイピングプログラムが構築できるようになります。
2026年のウェブ技術はより複雑化していますが、Seleniumの基本機能を正しく理解していれば、あらゆるデータ取得の要求に応えることが可能です。
今回解説したテクニックを自身のプロジェクトに活用し、効率的な自動化を実現してください。
