Pythonを用いたWebスクレイピングにおいて、Webサイト上の数値データが「1,234,567」のようにカンマで区切られているケースは非常に多く存在します。
BeautifulSoupを利用してこれらのデータを取得すると、数値ではなく「カンマを含む文字列」として読み込まれるため、そのままでは計算処理やグラフ作成に使用することができません。
データ分析や業務自動化において、取得したテキストを適切な数値型に変換する工程は、データクレンジングの基本として極めて重要です。
本記事では、BeautifulSoupで取得したテキストからカンマを効率的に除去し、Pythonの整数型(int)や浮動小数点型(float)へ変換する具体的な手法について詳しく解説します。
BeautifulSoupで取得した数値データの現状を確認する
まずは、BeautifulSoupでスクレイピングを行った際に、数値データがどのような状態で取得されるかを確認しましょう。
HTML上のテキストを取得すると、たとえ見た目が数値であっても、Python上では一律でstr型(文字列型)として扱われます。
以下のサンプルコードでは、カンマを含む金額データを取得し、そのデータ型を確認しています。
from bs4 import BeautifulSoup
# サンプルHTML
html_content = '<span class="price">1,280,000</span>'
soup = BeautifulSoup(html_content, 'html.parser')
# テキストの抽出
price_text = soup.find(class_='price').get_text()
print(f"取得した値: {price_text}")
print(f"データの型: {type(price_text)}")
取得した値: 1,280,000
データの型: <class 'str'>
実行結果から分かる通り、数字の間にカンマが含まれているため、このままint()関数で変換しようとするとエラーが発生します。
この問題を解決するためには、文字列操作メソッドを用いてカンマを明示的に取り除く必要があります。
replaceメソッドを使用した基本的なカンマ除去
最もシンプルで汎用性が高い方法は、Pythonの文字列標準メソッドであるreplace()を使用することです。
replace(',', '')と記述することで、文字列内のすべてのカンマを空文字に置き換えることができます。
カンマを除去した後は、int()やfloat()を用いることで、数値計算が可能な状態へと変換できます。
# カンマを除去して整数型に変換
clean_price = price_text.replace(',', '')
price_int = int(clean_price)
print(f"変換後の値: {price_int}")
print(f"計算の例 (10%引き): {price_int * 0.9}")
変換後の値: 1280000
計算の例 (10%引き): 1152000.0
この方法は、取得した文字列に「数値」と「カンマ」しか含まれていない場合に最適です。
シンプルで処理速度も速いため、まずはこの手法を検討するのが実務上の定石です。
正規表現を用いた複雑な文字列からの数値抽出
Webサイトによっては、「¥1,500 (税込)」や「単価:5,000円」といった具合に、数値以外の文字が混在している場合があります。
このようなケースでは、replace()を何度も重ねるよりも、reモジュール(正規表現)を使用する方が効率的です。
正規表現の\d(数字)を利用することで、カンマや通貨記号を除外して数字部分だけを抽出することが可能です。
import re
raw_data = "合計金額:¥1,500,000 (税込)"
# 数字以外の文字をすべて除去
numeric_string = re.sub(r'[^\d]', '', raw_data)
final_value = int(numeric_string)
print(f"抽出後の数値: {final_value}")
抽出後の数値: 1500000
上記コードのr'[^\d]'は「数字以外のあらゆる文字」にマッチし、それらをすべて削除(空文字に置換)しています。
これにより、カンマだけでなく、円記号や括弧といった不要なノイズを一気に取り除くことができます。
Pandasを使用して大量のデータを一括変換する
スクレイピングの結果をリスト化し、表形式で処理したい場合は、データ分析ライブラリ「Pandas」の活用が推奨されます。
PandasのSeriesやDataFrameには、文字列操作を列全体に適用できるstr.replace()メソッドが備わっています。
スクレイピングした大量のデータをリストに格納し、一気に数値化する際の手順を確認しましょう。
import pandas as pd
# BeautifulSoupで取得したと想定されるリスト
data_list = ["1,200", "5,500", "12,000", "300"]
# DataFrameの作成
df = pd.DataFrame(data_list, columns=['price'])
# カンマを除去して型を変換
df['price'] = df['price'].str.replace(',', '').astype(int)
print(df)
print(df.dtypes)
price
0 1200
1 5500
2 12000
3 300
price int64
dtype: object
このようにPandasを利用することで、ループ処理を記述することなく、数千件のデータも一瞬でクレンジングすることが可能です。
数値変換時に注意すべきポイント
数値への変換処理を行う際には、いくつかの注意点があります。
まず、対象の文字列が空(Noneや空文字)である場合、変換時にエラーが発生します。
また、欧州などの一部の地域では、カンマが桁区切りではなく「小数点」として使われる文化がある点にも留意してください。
変換エラーを防ぐための例外処理
スクレイピング対象のWebサイトに欠損値がある場合、プログラムが停止してしまいます。
これを防ぐためには、以下のようにtry-except構文を用いて安全に変換を行うのがベストプラクティスです。
def safe_int_convert(text):
try:
# カンマを除去して数値化
return int(text.replace(',', ''))
except (ValueError, AttributeError):
# 変換できない場合は0やNoneを返す
return 0
# テスト
print(safe_int_convert("2,500"))
print(safe_int_convert("")) # 空文字の場合
2500
0
桁区切り文字のバリエーションへの対応
多言語サイトをスクレイピングする場合、桁区切りがカンマではなく「スペース」や「ピリオド」である可能性があります。
データ変換前に、必ず対象サイトの数値フォーマットを目視で確認し、適切な置換ルールを設定してください。
一般的に、日本や米国のサイトであれば、「カンマを消去し、ピリオドを小数点として残す」というルールで問題ありません。
変換手法の比較まとめ
これまでに紹介した手法を、利用シーン別にまとめました。
| 手法 | 適したシーン | 主なメリット |
|---|---|---|
| replace() | 単純なカンマのみの除去 | 標準機能のみで高速・軽量 |
| re.sub() | 記号や単位が混在する場合 | 複雑なパターンも一括で除去可能 |
| Pandas | 大量のリスト・表データ処理 | 一括変換が可能で分析に繋げやすい |
まとめ
BeautifulSoupで取得した数値データは文字列型であるため、カンマを除去して数値型へ変換するステップが不可欠です。
もっとも基本的な方法は、文字列のreplace()メソッドを使用してカンマを取り除き、int()やfloat()でキャストすることです。
通貨記号や単位などが混ざっている複雑なテキストの場合は、正規表現(re.sub)を活用することで、柔軟かつ確実に数値部分だけを抽出できます。
さらに、大量のデータを一度に処理したい場合には、Pandasを利用した一括変換が非常に効率的です。
スクレイピング先のデータの特性に合わせて、今回紹介した手法を適切に使い分けてみてください。
