PandasでHTMLテーブルの読み書きをする

HTML (Hypertext Markup Language) はウェブページを構築するための標準的なマークアップ言語である。HTML の <table 要素を使って表形式のデータをレンダリングすることができます。Pandasのデータ解析ライブラリは、 read_html()to_html() といった関数を提供し、DataFrameにデータをインポートしたりエクスポートしたりすることができます。

この記事では、HTMLファイルから表形式データを読み込み、Pandas DataFrameにロードする方法を学びます。また、Pandas DataFrameからHTMLファイルへデータを書き込む方法も学びます。

注意: この記事では、HTML の <table 要素の読み込みと書き込みを行います。この記事には、HTMLファイル全体のパースは含まれていません。

HTMLの読み方

HTMLファイルのテーブルを読み込むには、 read_html() 関数を使用します。この関数はHTMLファイルのテーブルをPandasのDataFrameとして読み込みます。ファイルやURLから読み込むことができます。

それでは、各入力ソースを一つずつ見ていきましょう。

ファイルから HTML データを読み込む

このセクションでは、1組の入力データを使用します。1つのテーブルには、プログラミング言語とその作成年が含まれています。もう1つのテーブルは土地の大きさとその費用(USD)である。

以下のHTMLコンテンツをtable_data.htmlというファイルに保存してください。

<!DOCTYPE html

<html lang="en"
<head
<meta charset="utf-8"/
<titleTable Data</title
</head
<body
<table
<thead
<tr
<thProgramming Language</th
<thCreator</th
<thYear</th
</tr
</thead
<tbody
<tr
<tdC</td
<tdDennis Ritchie</td
<td1972</td
</tr
<tr
<tdPython</td
<tdGuido Van Rossum</td
<td1989</td
</tr
<tr
<tdRuby</td
<tdYukihiro Matsumoto</td
<td1995</td
</tr
</tbody
</table
<table
<thead
<tr
<th
          Area (sq.ft)
        </th
<th
          Price (USD)
        </th
</tr
</thead
<tbody
<tr
<td
          12000
        </td
<td
          500
        </td
</tr
<tr
<td
          32000
        </td
<td
          700
        </td
</tr
</tbody
</table
</body
</html


Pandas は HTML と XML ファイルをパースするために lxml という別のライブラリの助けを必要とします。read_html()関数を動作させるためには、lxml` をインストールする必要があります。

$ pip install lxml


lmxlがインストールされたら、read_html()` 関数を利用することができる。この関数はDataFrameのリストを返し、各DataFrameは与えられたHTMLファイルのテーブル要素全体となります。このリストにインデックスを付けることで、各テーブルにDataFrameとしてアクセスすることができます。

以下のコードは、HTMLファイルからテーブルを読み込むために read_html() 関数を使用することを示しています。

import pandas as pd


tables = pd.read_html('table_data.html')
print('Tables found:', len(tables))
df1 = tables[0]  # Save first table in variable df1
df2 = tables[1]  # Saving next table in variable df2


print('First Table')
print(df1)
print('Another Table')
print(df2)


Note: lxml がインストールされている必要がありますが、Pandasを動作させるためにプログラム内でインポートする必要はありません。

上記のコードをPythonインタープリターで実行すると、以下のような出力が得られます。

Tables found: 2
First Table
  Programming Language             Creator  Year
0                    C      Dennis Ritchie  1972
1               Python    Guido Van Rossum  1989
2                 Ruby  Yukihiro Matsumoto  1995
Another Table
   Area (sq.ft)  Price (USD)
0         12000          500
1         32000          700


URLからHTMLデータを読み込む

HTMLファイルからテーブル要素を読み込むのと同様に、read_html() を用いてHTML Webページからテーブル要素をDataFrameに読み込むことができます。ただし、ファイル名の代わりに、以下のようなURLを指定します。

read_html('https://en.wikipedia.org/wiki/Python_(programming_language)')


そして、それぞれのDataFrameが与えられたURLからテーブル要素を表しているDataFrameのリストを返します。

以下は、Pandasを使用してウェブサイトのURLからテーブル要素を読み取るサンプルコードです。

import pandas as pd


tables = pd.read_html('https://en.wikipedia.org/wiki/Python_(programming_language)')
print('Tables found:', len(tables))
df1 = tables[0]  # Save first table in variable df1
print('First Table')
print(df1.head())  # To print first 5 rows


上記のコードを正常に実行すると、次のような出力が得られます。

Tables found: 10
First Table
                0                                                  1
0             NaN                                                NaN
1        Paradigm  Multi-paradigm: functional, imperative, object...
2     Designed by                                   Guido van Rossum
3       Developer                         Python Software Foundation
4  First appeared                              1991; 29 years ago[1]


認証が必要な URL から HTML データを読み込む

ウェブサイトからテーブル要素を読み取ることができることは知っています。しかし、そのサイトが認証を必要とする場合、以下の例外が発生します。

raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 401: UNAUTHORIZED


このようなURLからデータを読み込むには、 requests モジュールを使用します。このモジュールは pip と一緒にインストールすることができる。

$ pip install requests


では、 requests ライブラリの get() メソッドを使用して、ウェブサイトの URL にリクエストを行いましょう。オプションで auth パラメータ (認証が必要なサイト) を指定することができます。

このメソッドは、Web ページからレスポンスオブジェクトを返します。ステータスコードを確認し (コンテンツが確かに存在することを確認するため)、レスポンスオブジェクトからテキストを取得し、テーブルを DataFrame に変換することができます。

では、requests を使って、認証を必要とするデータを取得する例を見てみましょう。この目的のために、https://httpbin.org を使用しています。

import requests


r = requests.get('https://httpbin.org/basic-auth/john/johnspassword', auth=('john', 'johnspassword'))


print(r.status_code)
print(r.text)


上記のコードを実行すると、以下のような出力が表示されます。

200
{
  "authenticated": true, 
  "user": "john"
}


これは、認証されたURLのWebページのコンテンツにアクセスすることに成功したことを示しています。しかし、このWebサイトにはJSONデータしか含まれておらず、DataFrameとしてHTMLのテーブル要素が必要です。

先ほどのURLにこだわって、requestsを使ってHTMLのテーブルをDataFrameとして読み込むことにしましょう。以前のサイトは公開されていましたが、認証されたコンテンツにアクセスする手順は同じです。

レスポンスを取得したら、 r.textread_html() メソッドに渡します。そして、いつものように、それが含むテーブルのリストをDataFramesとして取得します。

import pandas as pd
import requests


# Can use auth parameter for authenticated URLs
r = requests.get('https://en.wikipedia.org/wiki/Python_(programming_language)',
                 auth=('john', 'johnspassword'))
tables = pd.read_html(r.text)
print('Tables found:', len(tables))
df1 = tables[0]
print('First Table')
print(df1.head())


このコードを実行すると、次のような出力が生成されます。

Tables found: 10
First Table
                0                                                  1
0             NaN                                                NaN
1        Paradigm  Multi-paradigm: functional, imperative, object...
2     Designed by                                   Guido van Rossum
3       Developer                         Python Software Foundation
4  First appeared                              1991; 29 years ago[1]


PythonのPandasを使ったHTMLテーブルの書き方

HTMLのテーブルからデータを読み込むことに成功しました。それでは、PandasのDataFrameをHTMLファイルに書き込んでみましょう。これは to_html() メソッドを使用することで実現できます。

to_html()`には、データを書き出したいファイルのパスが渡されます。絶対パスを指定しない場合は、カレントディレクトリからの相対パスで保存されます。

このように、DataFrameをHTMLのテーブルにエクスポートすることができます。

import pandas as pd


df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df.to_html('write_html.html')


このコードは、カレントディレクトリに次のようなファイル write_html.html を生成します。

<table border="1" class="dataframe"
<thead
<tr style="text-align: right;"
<th</th
<thA</th
<thB</th
</tr
</thead
<tbody
<tr
<th0</th
<td1</td
<td3</td
</tr
<tr
<th1</th
<td2</td
<td4</td
</tr
</tbody
</table


エクスポートされるのは、HTMLドキュメント全体ではなく、HTMLテーブルそのものであることに注意してください。

PythonのPandasでスタイル付きHTMLテーブルを作る

見ての通り、デフォルトではテーブルのボーダーは1、アライメントは右、そして<thタグの中にDataFrameのインデックスを持っています。このデフォルトの構造は、いくつかのオプションのパラメータを指定することで変更することができます。

インデックスを隠す

テーブルの出力にインデックスを含めたくない場合は、to_html()の中で index=False を設定することができます。

import pandas as pd


df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df.to_html('write_html.html', index=False)


このコードは、以下の内容を持つ write_html.html ファイルを生成します。

<table border="1" class="dataframe"
<thead
<tr style="text-align: right;"
<thA</th
<thB</th
</tr
</thead
<tbody
<tr
<td1</td
<td3</td
</tr
<tr
<td2</td
<td4</td
</tr
</tbody
</table


チェンジングテーブルボーダー

テーブルのボーダーのデフォルトは 1 ピクセルです。このデフォルトを変更するには、borderパラメータにピクセル単位で値を設定します。

次のコードは、ボーダーを3ピクセルに変更します。

import pandas as pd


df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df.to_html('write_html.html', border=3)


生成されたファイルでは、テーブルのボーダー属性が「3」に設定されています。

<table border="3" class="dataframe"
<thead
<tr style="text-align: right;"
<th</th
<thA</th
<thB</th
</tr
</thead
<tbody
<tr
<th0</th
<td1</td
<td3</td
</tr
<tr
<th1</th
<td2</td
<td4</td
</tr
</tbody
</table


文字揃え

デフォルトでは、テーブルの先頭テキストは右寄せになります。この配置を変更するには、 justify パラメータを使用します。例えば、justify="center" とすると、<thead タグの <tr タグ内に style="text-align: center;" が追加されます。

それでは、headのテキストをセンター揃えにし、結果を見てみましょう。

import pandas as pd


df = pd.DataFrame({'A': [1, 'AAA'], 'B': ['BBB', 4]})
df.to_html('write_html.html', justify='center')


上記のコードで作成されたテーブルは、以下のようになります。

<table border="1" class="dataframe"
<thead
<tr style="text-align: center;"
<th</th
<thA</th
<thB</th
</tr
</thead
<tbody
<tr
<th0</th
<td1</td
<tdBBB</td
</tr
<tr
<th1</th
<tdAAA</td
<td4</td
</tr
</tbody
</table


テーブルのheadのテキストがきれいに中央揃えになりました。

結論

I

タイトルとURLをコピーしました