DEV Community

Cover image for ブラウザからデータベースへ:Webテーブルの最短インポート方法
circobit
circobit

Posted on

ブラウザからデータベースへ:Webテーブルの最短インポート方法

Webサイトでデータを見つけた。それをデータベースに入れたい。

A地点からB地点への最速ルートは?

このガイドでは、HTMLテーブルをSQLite、PostgreSQL、MySQLなどのデータベースに取り込む実践的なワークフローを、最小限の手間で解説します。

基本ワークフロー

ブラウザからデータベースへのパイプラインは、すべて同じステップで構成されます:

  1. 抽出 — Webページからテーブルを取り出す
  2. クリーニング — フォーマット、型、構造を修正する
  3. ロード — データベースに挿入する

問題は、各ステップをどこで、どのツールで行うかです。

パス1:CSVを中間ファイルとして使う

最も一般的なアプローチ。どのデータベースでも使えます。

ステップ1:CSVにエクスポート

HTML Table Exporterなどのブラウザ拡張機能を使うか、スプレッドシートにコピー&ペーストしてCSVとして保存します。

重要なポイント: デリミタの選択。カンマはデータにカンマが含まれていない限り有効です。セミコロンやタブの方がデータが複雑な場合は安全です。

ステップ2:データベースにロード

SQLite:

sqlite3 mydb.db
.mode csv
.import data.csv tablename
Enter fullscreen mode Exit fullscreen mode

ヘッダー付きの場合:

sqlite3 mydb.db <<EOF
.mode csv
.headers on
.import data.csv tablename
EOF
Enter fullscreen mode Exit fullscreen mode

PostgreSQL:

COPY tablename FROM '/path/to/data.csv' 
WITH (FORMAT csv, HEADER true);
Enter fullscreen mode Exit fullscreen mode

またはpsqlで:

\copy tablename FROM 'data.csv' WITH (FORMAT csv, HEADER true);
Enter fullscreen mode Exit fullscreen mode

MySQL:

LOAD DATA INFILE '/path/to/data.csv'
INTO TABLE tablename
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;
Enter fullscreen mode Exit fullscreen mode

メリットとデメリット

  • 汎用性が高い
  • 中間ファイルを確認できる
  • ロード前に手動で問題を修正できる
  • 追加のステップが必要
  • 型推論が基本的

パス2:SQL文に直接変換

テーブルを直接INSERT文としてエクスポートします。

SQLとしてエクスポート

一部のエクスポートツールはSQLを直接生成します。出力はこのようになります:

INSERT INTO table_name (col1, col2, col3) VALUES
('value1', 'value2', 123),
('value4', 'value5', 456);
Enter fullscreen mode Exit fullscreen mode

ロード

SQLファイルを実行するだけです:

# SQLite
sqlite3 mydb.db < data.sql

# PostgreSQL
psql -d mydb -f data.sql

# MySQL
mysql mydb < data.sql
Enter fullscreen mode Exit fullscreen mode

メリットとデメリット

  • エクスポートからデータベースまでワンステップ
  • SQLはデータベース間でほぼポータブル
  • 大規模データセット=巨大なSQLファイル
  • テーブルスキーマを事前に定義する必要がある

パス3:Python + Pandasパイプライン

最大の柔軟性。繰り返しインポートや複雑なクリーニングに最適。

完全なワークフロー

import pandas as pd
from sqlalchemy import create_engine

# ステップ1:CSVをロード(ブラウザからエクスポートしたもの)
df = pd.read_csv('data.csv')

# ステップ2:クリーニング
df.columns = df.columns.str.lower().str.replace(' ', '_')  # 列名を正規化
df['date'] = pd.to_datetime(df['date'])  # 日付をパース
df['amount'] = df['amount'].str.replace('[$,]', '', regex=True).astype(float)  # 通貨をクリーニング

# ステップ3:データベースにロード
engine = create_engine('sqlite:///mydb.db')
# または: create_engine('postgresql://user:pass@localhost/mydb')
# または: create_engine('mysql+pymysql://user:pass@localhost/mydb')

df.to_sql('tablename', engine, if_exists='replace', index=False)
Enter fullscreen mode Exit fullscreen mode

型マッピング

Pandasは型を推論しますが、明示的に指定することもできます:

df.to_sql('tablename', engine, 
          if_exists='replace', 
          index=False,
          dtype={
              'id': Integer(),
              'name': String(100),
              'created_at': DateTime(),
              'amount': Float()
          })
Enter fullscreen mode Exit fullscreen mode

メリットとデメリット

  • クリーニングと型の完全な制御
  • 複雑な変換に対応
  • 再現可能でスクリプト化できる
  • Python環境が必要
  • 一回限りのインポートにはやりすぎ

パス4:DuckDB(モダンなショートカット)

DuckDBはCSVを直接読み込み、ほとんどのクリーニングを自動で処理します。

直接クエリ

-- インポートせずにCSVをクエリ
SELECT * FROM 'data.csv';

-- 型推論付き
SELECT * FROM read_csv_auto('data.csv');

-- CSVからテーブルを作成
CREATE TABLE mytable AS SELECT * FROM 'data.csv';
Enter fullscreen mode Exit fullscreen mode

ブラウザからクエリまで数秒で

# ブラウザからCSVとしてテーブルをエクスポート
# そのまますぐにクエリ:
duckdb -c "SELECT column1, SUM(column2) FROM 'data.csv' GROUP BY column1;"
Enter fullscreen mode Exit fullscreen mode

スキーマ定義不要。インポートステップ不要。そのままクエリ。

メリットとデメリット

  • アドホック分析に最速
  • 優れた型推論
  • SQLインターフェース
  • 従来型のデータベースではない(永続化するには結果をエクスポート)

よくある問題の対処法

スペースを含む列名

Webテーブルのヘッダーには「Total Sales」や「Year to Date」のようなものが多い。

エクスポート時に修正: 一部のツールはヘッダーを自動的に正規化します。

インポート時に修正:

df.columns = df.columns.str.replace(' ', '_').str.lower()
Enter fullscreen mode Exit fullscreen mode

またはインポート後にSQLで:

ALTER TABLE mytable RENAME COLUMN "Total Sales" TO total_sales;
Enter fullscreen mode Exit fullscreen mode

異なる数値フォーマット

ヨーロッパ式(1.234,56)とUS式(1,234.56)のフォーマットがインポートを壊します。

インポート前に修正: クリーニングプリセット付きのツールを使うか:

# ヨーロッパ式を標準に変換
df['value'] = df['value'].str.replace('.', '').str.replace(',', '.').astype(float)
Enter fullscreen mode Exit fullscreen mode

NULL表現

Webテーブルでは空白、「N/A」、「—」、「-」で欠損データを表します。

df = df.replace(['N/A', '', '-', ''], pd.NA)
Enter fullscreen mode Exit fullscreen mode

またはDuckDBで:

SELECT NULLIF(column, 'N/A') AS column FROM 'data.csv';
Enter fullscreen mode Exit fullscreen mode

さまざまな日付フォーマット

df['date'] = pd.to_datetime(df['date'], format='mixed', dayfirst=True)
Enter fullscreen mode Exit fullscreen mode

format='mixed' は同じ列内の不統一な日付フォーマットに対応します。

適切なパスの選び方

シナリオ 推奨パス
一回限りのインポート、小さなテーブル CSV + データベース直接インポート
一回限りのインポート、クリーニングが必要 Python + Pandas
迅速な分析、永続化不要 DuckDB
同じソースからの定期インポート Pythonスクリプト(自動化)
共有/バージョン管理用にSQL形式が必要 SQL直接エクスポート

実例:完全なワークフロー

Webサイトに製品データのテーブルがあるとします。

ステップ1: HTML Table Exporterでエクスポート → 数値がクリーニングされたCSV

ステップ2: DuckDBで簡易検証:

SELECT COUNT(*), COUNT(DISTINCT product_id) FROM 'products.csv';
-- 重複チェック
Enter fullscreen mode Exit fullscreen mode

ステップ3: PostgreSQLにロード:

import pandas as pd
from sqlalchemy import create_engine

df = pd.read_csv('products.csv')
engine = create_engine('postgresql://user:pass@localhost/inventory')
df.to_sql('products', engine, if_exists='replace', index=False)
Enter fullscreen mode Exit fullscreen mode

合計時間:2分。

本質的な教訓

最短のパスが必ずしも最も直接的なルートとは限りません。

エクスポート時のクリーニングに30秒かけることで、インポートエラーのデバッグに10分を節約できます。適切な中間フォーマット(CSV vs SQL vs JSON)の選択は、ターゲットデータベースとデータの複雑さに依存します。

ほとんどのWebテーブル → データベースのワークフローでは:

  1. 数値/日付クリーニング付きでCSVにエクスポート
  2. データベースのネイティブCSVインポートでロード
  3. 複雑な変換が必要な場合のみPythonを使用

シンプルなパイプラインこそ保守しやすいパイプラインです。

Pythonワークフローの詳細については、WebテーブルをPython & Pandas用にJSONにエクスポートする方法のガイドをご覧ください。


データベースに直接取り込めるクリーンなエクスポートが必要ですか?gauchogrid.com/ja/html-table-exporterで詳細を確認するか、Chrome ウェブストアでHTML Table Exporterを無料でお試しください。

Top comments (0)