Webサイト上の表データや、ローカルにあるHTMLファイル内のテーブル情報を解析し、DataFrameとして取り込むには pd.read_html 関数を使用します。
本記事では、読み込み対象となるHTMLファイルと、それを読み込むPythonスクリプトを明確に分けた実装例、および主要なパラメータについて解説します。
目次
read_htmlの主要パラメータ
read_html でテーブルデータの解釈を調整するための主要なオプションは以下の通りです。
| パラメータ | 意味・役割 | 指定例 |
| header | ヘッダー(列名)として使用する行番号を指定します。0 なら1行目、1 なら2行目をヘッダーとして扱います。 | 0, 1 |
| index_col | DataFrameのインデックス(行ラベル)として使用する列を指定します。列番号(0始まり)で指定可能です。 | 0, 1 |
| flavor | HTMLの解析エンジンを指定します。HTML構文が崩れている場合などに変更します。 | "lxml", "bs4", "html5lib" |
| attrs | 特定の id や class を持つテーブルのみを抽出する場合に、その属性を辞書で指定します。 | {"id": "target_table"} |
実装サンプル
ここでは、ローカルに保存されたHTMLファイル(table_page.html)をPythonから読み込むシチュエーションを想定します。
1. 読み込み対象のHTMLファイル
まず、解析対象となるHTMLファイルを作成します。ここでは2つの異なる構造のテーブルを配置しています。ファイル名は table_page.html とします。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Sample Table Page</title>
</head>
<body>
<h1>製品リスト(ヘッダーあり)</h1>
<table id="product_table" border="1">
<thead>
<tr>
<th>Product_ID</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>101</td>
<td>Desktop PC</td>
<td>120000</td>
</tr>
<tr>
<td>102</td>
<td>Monitor</td>
<td>35000</td>
</tr>
</tbody>
</table>
<br>
<h1>社員名簿(ヘッダーなし・変則的)</h1>
<table id="employee_table" border="1">
<tr>
<td>Emp_001</td>
<td>T.Suzuki</td>
<td>Sales</td>
</tr>
<tr>
<td>Emp_002</td>
<td>M.Sato</td>
<td>Engineering</td>
</tr>
</table>
</body>
</html>
2. テーブルを読み込むPythonコード
次に、上記のHTMLファイルを読み込み、DataFrameとして処理するPythonコードです。
read_html はページのURLだけでなく、ローカルのファイルパスも引数として受け取ることができます。
import pandas as pd
def read_html_tables():
"""
HTMLファイルからテーブルデータを読み込み、
パラメータによる挙動の違いを確認する関数
"""
# 読み込む対象のHTMLファイルパス
file_path = "table_page.html"
print("=== 1. 基本的な読み込み ===")
# read_htmlは、検出されたすべてのテーブルを「DataFrameのリスト」として返します
# そのため、戻り値を受け取る変数は複数形(tables)にするのが一般的です
try:
tables = pd.read_html(file_path)
except ValueError as e:
print(f"エラー: {e}")
return
print(f"検出されたテーブル数: {len(tables)}")
# 1つ目のテーブルを表示 (Product_IDなどがヘッダーとして認識される)
print("\n--- テーブル1 (df_products) ---")
df_products = tables[0]
print(df_products)
print("\n=== 2. パラメータを指定した読み込み ===")
# 2つ目のテーブル(社員名簿)をターゲットにする
# header=None: ヘッダー行がないことを明示 (0行目もデータとして扱う)
# index_col=0: 0列目(Emp_ID)をインデックスとして使用
# flavor="bs4": 解析エンジンにBeautifulSoupを指定 (柔軟な解析)
tables_custom = pd.read_html(
file_path,
header=None,
index_col=0,
flavor="bs4" # html5libなどを指定する場合もあります
)
# 2つ目のテーブルを取得
# HTML内の順序通りに格納されているため、インデックス1を指定
if len(tables_custom) > 1:
df_employees = tables_custom[1]
# わかりやすくするために列名を手動で設定
df_employees.columns = ["Name", "Department"]
print("\n--- テーブル2 (df_employees) ---")
print(df_employees)
if __name__ == "__main__":
# 事前に 'table_page.html' がカレントディレクトリに存在することを確認してください
read_html_tables()
実行結果
=== 1. 基本的な読み込み ===
検出されたテーブル数: 2
--- テーブル1 (df_products) ---
Product_ID Name Price
0 101 Desktop PC 120000
1 102 Monitor 35000
=== 2. パラメータを指定した読み込み ===
--- テーブル2 (df_employees) ---
Name Department
0
Emp_001 T.Suzuki Sales
Emp_002 M.Sato Engineering
注意点
- 依存ライブラリ: この機能を使用するには、
lxml、html5lib、beautifulsoup4などのHTMLパーサーライブラリを追加でインストールしておく必要があります(例:pip install lxml html5lib beautifulsoup4)。 - 戻り値の型:
read_htmlの戻り値は常に リスト です。テーブルが1つしかなくても[DataFrame]という形式で返ってくるため、tables[0]のようにインデックスで個別のDataFrameを取り出す必要があります。
