Webサイトで完璧なデータセットを見つけました。これをPandasに取り込みたい。
従来のアプローチ:
import pandas as pd
# Webサイトの構造がシンプルであることを祈る
tables = pd.read_html('https://example.com/data')
# どのテーブルか推測する
df = tables[0] # たぶん?見てみよう...
# 問題が発覚
print(df.dtypes)
# すべてが 'object'(文字列)
# 数値にカンマが入っている
# 日付がパースできない
# カラム名にスペースが入っている
# 30分かけてクリーニング...
もっと速い方法をお見せします。
pd.read_html() の問題点
Pandasの read_html() は便利ですが限界があります:
テーブルの選択ができない — すべてのテーブルを取得。どのインデックスか推測する必要がある。
クリーニングなし — "1,234,567" のような数値は文字列のまま。
CORSの問題 — 多くのサイトがプログラムによるアクセスをブロック。
JavaScriptレンダリング — 動的テーブルは生のHTMLには存在しない。
認証 — ログインが必要なコンテンツにアクセスできない。
簡単なスクリプトなら動きます。本格的な分析には、もっと良い方法が必要です。
30秒ワークフロー
実際のやり方はこうです:
ステップ1:ブラウザからエクスポート(5秒)
HTML Table Exporter を使って:
- 欲しいテーブルをクリック
- 拡張機能アイコンをクリック
- 「For Pandas」プロファイルを選択
- ハイライトされたテーブルからCSVでエクスポート
拡張機能はブラウザが表示しているものをそのまま見ます — JavaScriptレンダリングされたコンテンツ、認証済みページ、すべて。
ステップ2:Pandasで読み込み(5秒)
import pandas as pd
df = pd.read_csv('export.csv')
print(df.dtypes)
以上です。データはすでにクリーンです。
「クリーン」の具体的な意味
「For Pandas」プロファイルでエクスポートすると、拡張機能が以下を処理します:
数値の正規化
前: "1.234.567,89" (ヨーロッパフォーマット)
後: 1234567.89 (float)
前: "$1,234.56"
後: 1234.56
CSVには正規化された数値が含まれ、Pandasが正しくパースします:
# クリーニングなしの場合:
df['revenue'].sum() # TypeError: can only concatenate str
# クリーニング済みの場合:
df['revenue'].sum() # 4892341.50 ✓
Boolean変換
前: "Yes", "No", "Y", "N", "True", "False"
後: true, false
# フィルターがすぐ動く
active_users = df[df['is_active'] == True]
Null処理
前: "-", "N/A", "n/a", "", "null", "—"
後: (空、NaNとしてパース)
# Null検出が正常に動作
df['optional_field'].isna().sum() # 正確なカウント
snake_caseヘッダー
前: "Revenue ($M)", "User Count", "Growth Rate %"
後: revenue_m, user_count, growth_rate
# クリーンなカラムアクセス
df['revenue_m'] # df['Revenue ($M)'] の代わりに
実例:FBRefのサッカー統計
プレミアリーグの選手統計をFBRefから取得したいとします。
従来の方法
import pandas as pd
import requests
from bs4 import BeautifulSoup
url = 'https://fbref.com/en/comps/9/stats/Premier-League-Stats'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# 正しいテーブルを見つける(たくさんある)
table = soup.find('table', {'id': 'stats_standard'})
# 手動でパース(ヘッダーが複雑なため)
# FBRefはグループ化ヘッダーを使用:"Playing Time" が複数列にスパン
# これが pd.read_html() を壊す
# 45分後...
新しい方法
- ブラウザでFBRefを開く
- 拡張機能をクリック → テーブルを選択 → 「For Pandas」プロファイルでエクスポート
- 読み込み:
df = pd.read_csv('fbref_stats.csv')
print(df.columns.tolist())
# ['player', 'nation', 'squad', 'playing_time_mp',
# 'playing_time_starts', 'performance_gls', ...]
グループヘッダー("Playing Time"、"Performance")がサブヘッダーと自動的にマージされます。
もう書かなくていいコード
以前、Webスクレイピングのたびに書いていたクリーンアップコード:
def clean_web_data(df):
"""もう必要ない関数"""
for col in df.select_dtypes(include='object'):
try:
cleaned = df[col].str.replace(r'[$€£¥]', '', regex=True)
cleaned = cleaned.str.replace(',', '')
df[col] = pd.to_numeric(cleaned, errors='ignore')
except:
pass
bool_map = {
'yes': True, 'no': False,
'true': True, 'false': False,
'y': True, 'n': False,
'1': True, '0': False,
}
for col in df.columns:
if df[col].str.lower().isin(bool_map.keys()).all():
df[col] = df[col].str.lower().map(bool_map)
null_values = ['', '-', 'N/A', 'n/a', 'null', 'NULL', '—', '–']
df = df.replace(null_values, np.nan)
df.columns = (df.columns
.str.lower()
.str.replace(r'[^a-z0-9]+', '_', regex=True)
.str.strip('_'))
return df
この関数はすべてのデータセットで実行していました。今はエクスポートが処理してくれます。
いつ何を使うか
| シナリオ | 最適なアプローチ |
|---|---|
| 一回限りの分析 | ブラウザエクスポート → CSV → Pandas |
| 繰り返しスクレイピング | Pythonスクリプト + requests
|
| JavaScript多用サイト | ブラウザエクスポート(レンダリング済みコンテンツを表示) |
| 認証済みデータ | ブラウザエクスポート(セッションを使用) |
| APIが利用可能 | APIを直接使用 |
| シンプルな静的テーブル |
pd.read_html() で十分 |
プロのヒント:複雑なデータにはJSON
ネストされたデータや型付きデータには、JSONでエクスポート:
import pandas as pd
import json
with open('export.json') as f:
data = json.load(f)
df = pd.DataFrame(data)
JSONエクスポートは型を保持します:
- 数値は数値(文字列ではなく)
- Booleanはboolean
- NullはNull
print(df.dtypes)
# player object
# goals int64 # すでに数値!
# is_starter bool # すでにboolean!
# injury_date object # datetimeにパース可能
JSONワークフローの詳細は、HTMLテーブルスクレイパー Chrome拡張機能ガイドをご覧ください。
ワークフローまとめ
旧ワークフロー(30分以上):
- スクレイピングスクリプトを書く
- CORS/認証の問題に対処
- 複雑なHTMLをパース
- 数値をクリーニング
- Booleanをクリーニング
- Nullをクリーニング
- カラム名を修正
- エッジケースをデバッグ
- ようやく:分析
新ワークフロー(30秒):
- 拡張機能をクリック
- クリーニングプロファイルでエクスポート
pd.read_csv()- 分析
試してみよう
- HTML Table Exporter をインストール
- 分析したいテーブルを見つける
- クリーニングプリセットでエクスポート
- Pandasで読み込み
無料版で基本的なエクスポートが可能。PROはPandas最適化出力のためのクリーニングプリセットとプロファイルを追加します。
詳しくは gauchogrid.com/ja/html-table-exporter をご覧いただくか、Chrome Web Store でお試しください。
WebデータをPandasに取り込む現在のワークフローは?クリーニングステップにどれくらい時間を費やしていますか?コメントで教えてください。
Top comments (0)