Pandas で HTML テーブルを読み込む

Pandas のpd.read_html()関数は Web ページ内の HTML テーブルデータを自動的に解析し、DataFrame に変換します。これは Web データのスクレイピング、株価の分析、金融情報の取得などのシーンで非常に役立ちます。


基本的な使い方

read_html()関数は Web ページ内のすべての HTML テーブル要素を検索して読み込み、DataFrame のリストを返します。

単一のテーブルを読み込む

例

import pandas as pd

# Webページ上のすべてのテーブルを読み込む
# 注意:lxml と beautifulsoup4 ライブラリのサポートが必要です
# pip install lxml beautifulsoup4

# URLから読み込む
tables = pd.read_html("https://example.com/table.html")

# 見つかったテーブルの数を確認する
print(f"テーブルが {len(tables)} 個見つかりました")

# 最初のテーブルを取得する
df = tables[0]
print(df.head())

複数のテーブルを読み込む

1つのWebページに複数のテーブルが含まれる場合があります。read_html()リストが返されるので、インデックスで選択できます:

例

import pandas as pd

# Webページに複数のテーブルがあると仮定する
tables = pd.read_html("https://example.com/data.html")

# すべてのテーブルをループ処理する
for i, table in enumerate(tables):
    print(f"\n=== テーブル {i+1} ===)
    print(f"形状: {table.shape}")
    print(table.head(3))

よく使うパラメータの詳細

パラメータ 説明 例
io 入力ソース。URL、ファイルパス、または文字列を指定できます "page.html"
match 正規表現マッチング。特定のテキストを含むテーブルをフィルタリングします match="销售额"
header ヘッダー行のインデックスを指定します header=0
attrs HTML属性でテーブルをフィルタリングします attrs={"id": "table1"}
skiprows 指定した行をスキップします skiprows=[0, 1]
na_values 欠損値として扱う文字列を指定します na_values=["N/A"]

match パラメータを使ってテーブルをフィルタリングする

例

import pandas as pd

# match パラメータを使って、特定のテキストを含むテーブルのみを返す
# 例: "股票" という文字を含むテーブルだけを読み込む
tables = pd.read_html(
    "https://example.com/finance.html",
    match="股票"
)

if tables:
    df = tables[0]
    print(df)

attrs パラメータを使ってテーブルを正確に特定する

例

import pandas as pd

# HTML属性を使ってテーブルを特定する
# 例: id="stock-table" のテーブルを取得する
tables = pd.read_html(
    "https://example.com/data.html",
    attrs={"id": "stock-table"}  # id="stock-table" の table 要素を検索する
)

# または class で特定する
tables = pd.read_html(
    "https://example.com/data.html",
    attrs={"class": "data-table"}
)

df = tables[0]
print(df)

実践例:Webページから株価データを取得する

次の例では、金融サイトから株式リストのデータを取得する方法を示します。

例

import pandas as pd
from io import StringIO


# デモ用に模擬的な HTML コンテンツを作成する
# 実際に使用する際は実際の URL に置き換える
html_content = '''
<table border="1">
    <tr>
<th>股票代码</th>
<th>股票名称</th>
<th>收盘价</th>
<th>涨跌幅</th>
    </tr>
    <tr>
        <td>600519</td>
<td>贵州茅台</td>
        <td>1850.00</td>
        <td>2.35%</td>
    </tr>
    <tr>
        <td>000858</td>
<td>五粮液</td>
        <td>185.50</td>
        <td>-1.20%</td>
    </tr>
    <tr>
        <td>601318</td>
<td>中国平安</td>
        <td>52.30</td>
        <td>0.85%</td>
    </tr>
</table>
'''


# 文字列からテーブルを読み込む

tables = pd.read_html(StringIO(html_content))

df = tables[0]

print("元のテーブル:")
print(df)
print()

# データクレンジング:涨跌幅列を処理する
df["涨跌幅"] = df["涨跌幅"].str.replace("%", "").astype(float)
df["收盘价"] = df["收盘价"].astype(float)

print("クレンジング後のデータ:")
print(df)

StringIO の役割は、文字列をファイルオブジェクトのように見せかけることです。これにより pandas はファイルストリームを読み込むロジックで処理し、パスや URL と誤判定しません。

出力:

原始表格:
     股票代码  股票名称     收盘价     涨跌幅
0  600519  贵州茅台  1850.0   2.35%
1     858   五粮液   185.5  -1.20%
2  601318  中国平安    52.3   0.85%

清洗后的数据:
     股票代码  股票名称     收盘价   涨跌幅
0  600519  贵州茅台  1850.0  2.35
1     858   五粮液   185.5 -1.20
2  601318  中国平安    52.3  0.85

Wikipedia のテーブルを読み込む

例

import pandas as pd

# Wikipedia ページ内のテーブルを読み込む
# 各国の人口リストを例にする
url = "https://en.wikipedia.org/wiki/List_of_countries_by_population_(United_Nations)"

try:
    tables = pd.read_html(url)
    print(f"このページには {len(tables)} 個のテーブルがあります")

    # 通常、最初のテーブルが必要なものです
    df = tables[0]
    print(df.head(10))
except Exception as e:
    print(f"読み込み失敗: {e}")
    print("必要なライブラリがインストールされていることを確認してください: pip install lxml beautifulsoup4")

データクレンジングと処理

Webページから読み込んだテーブルは、分析に使用する前にさらにクレンジングが必要なことがよくあります。

よくあるクレンジング操作

例

import pandas as pd
from io import StringIO

# さまざまな汚いデータを含むテーブルを模擬する
html_content = '''
<table>
<tr><th>日期</th><th>产品</th><th>销量</th><th>备注</th></tr>
<tr><td>2024-01-01</td><td>产品A</td><td>1,234</td><td>N/A</td></tr>
<tr><td>2024-01-02</td><td>产品B</td><td>567</td><td>缺货</td></tr>
<tr><td>2024-01-03</td><td>产品C</td><td>--</td><td>未统计</td></tr>
</table>
'''


df = pd.read_html(StringIO(html_content))[0]
print("元のデータ:")
print(df)
print()

# クレンジング手順
# 1. 列名を変更する
df.columns = ["日期", "产品", "销量", "备注"]

# 2. 欠損値を処理する
df = df.replace(["N/A", "--", "未统计", "缺货"], pd.NA)

# 3. 数値列をクレンジングする(カンマを除去)
df["销量"] = df["销量"].str.replace(",", "").replace(pd.NA, None)
df["销量"] = pd.to_numeric(df["销量"], errors="coerce")

# 4. 日付を変換する
df["日期"] = pd.to_datetime(df["日期"])

print("クレンジング後:")
print(df)
print("\n"データ型:")
print(df.dtypes)

出力:

原始数据:
           日期   产品    销量   备注
0  2024-01-01  产品A  1234  NaN
1  2024-01-02  产品B   567   缺货
2  2024-01-03  产品C    --  未统计

清洗后:
          日期   产品      销量    备注
0 2024-01-01  产品A  1234.0   NaN
1 2024-01-02  产品B   567.0  <NA>
2 2024-01-03  产品C     NaN  <NA>

数据类型:
日期    datetime64[ns]
产品            object
销量           float64
备注            object
dtype: object

注意事項とよくある問題

1. 依存ライブラリのインストール

read_html()必要なlxmlとbeautifulsoup4ライブラリ:

pip install lxml beautifulsoup4

2. ネットワークの問題

ネットワーク URL を読み込む際、ネットワーク遅延やアクセス制限に遭遇する可能性があります。適切なタイムアウト設定を追加するか、ローカルキャッシュを使用することをお勧めします。

3. テーブル構造が複雑

一部の Web ページのテーブルは、セル結合やネストされたテーブルなどの複雑な構造を使用しており、解析に失敗する可能性があります。その場合は、BeautifulSoup を使用して HTML を直接解析することを試みてください。

4. データの完全性

Web ページのデータは随時変化する可能性があるため、読み込み後にデータの完全性を検証し、元のデータソースと比較することをお勧めします。

Web データを取得する際は、Web サイトの robots.txt ルールと関連する法律・規制を遵守し、サーバーに負担をかけないよう頻繁なリクエストは避けてください。


まとめ

pd.read_html()Pandas の HTML テーブル読み込みは、Web ページのテーブルデータを取得するための強力なツールであり、HTML テーブルをすばやく DataFrame に変換できます。実際の使用では、依存ライブラリのインストール、ネットワーク問題の処理、汚いデータのクレンジングなどに注意する必要があります。取得したデータは通常、分析に使用する前にさらに処理が必要です。Pandas のデータクレンジング機能と組み合わせて使用することをお勧めします。

その他の拡張