テーブルをエクスポートする。CSVを開く。「José」の代わりに「José」が表示される。「€」の代わりに「€」。emダッシュの代わりに「â€"」。
エンコーディング地獄へようこそ。
このガイドでは、なぜそうなるのか、そして手動エクスポートでも抽出ツール構築でも、どう修正するかを説明します。
実際に何が起きているか
文字エンコーディングとは、コンピュータがテキストをバイトとして表現する方法です。異なるエンコーディングは同じ文字に対して異なるバイトパターンを使用します。
最も一般的な原因:UTF-8がLatin-1として解釈される(またはその逆)。
UTF-8は非ASCII文字に複数バイトを使用します。ソフトウェアがそれらのバイトをLatin-1(シングルバイトエンコーディング)として読むと、各バイトが個別の文字化けした文字になります。
| 文字 | UTF-8バイト | Latin-1として誤読 |
|---|---|---|
| é | C3 A9 | é |
| € | E2 82 AC | € |
| — | E2 80 94 | â€" |
| ñ | C3 B1 | ñ |
パターンは一貫しています:マルチバイトシーケンスが複数の誤った文字になります。
エンコーディングが壊れる場所
1. ソースページ
Webサイトが一つのエンコーディングを宣言しているのに、別のものを配信する場合。または何も宣言せず、ブラウザに推測させる場合。
<!-- UTF-8を宣言 -->
<meta charset="UTF-8">
<!-- しかしサーバーは以下を送信 -->
Content-Type: text/html; charset=ISO-8859-1
宣言が矛盾する場合、ブラウザは通常うまく処理します。エクスポートツールはそうでないかもしれません。
2. エクスポートプロセス
抽出ツールがエンコーディングを保持しない場合、バイトが再解釈されます。
JavaScriptの textContent はUnicode文字列を返すので安全です。しかしファイルへの変換にはエンコーディングの選択が必要です。その選択が誤っていると、破損が発生します。
3. ファイルを開くアプリケーション
有効なUTF-8のCSVをエクスポートした。Excelが推測を誤ってLatin-1で開く。同じ破損、異なる原因。
同じファイルが一つのアプリケーションでは正常に見え、別のアプリケーションでは壊れて見える理由です。
問題の診断方法
パターン認識
特定の文字化けは診断的です:
| 表示される文字 | 元の文字 |
|---|---|
| á, é, Ã, ó, ú | á, é, í, ó, ú(スペイン語アクセント) |
| ä, ö, ü | ä, ö, ü(ドイツ語ウムラウト) |
| ç | ç(セディーユ) |
| € | €(ユーロ記号) |
| â€" | —(emダッシュ) |
| ’ | '(カーリーアポストロフィ) |
à の後に別の文字が続く場合、UTF-8がLatin-1として読まれています。
生バイトの確認
Pythonで:
with open('file.csv', 'rb') as f:
print(f.read(100))
「é」を期待する場所に \xc3\xa9 が見えれば、ファイルはUTF-8です。\xe9 が見えれば、Latin-1です。
ページの宣言を確認
ブラウザ開発者ツールで:
document.characterSet // 使用されている実際のエンコーディングを返す
破損ファイルの修正
再エンコードの技
UTF-8がLatin-1として誤読された場合、逆の操作ができます:
# Latin-1として読む(誤って解釈された方法)
with open('corrupted.csv', 'r', encoding='latin-1') as f:
text = f.read()
# Latin-1バイトに戻してエンコードし、UTF-8としてデコード
fixed = text.encode('latin-1').decode('utf-8')
with open('fixed.csv', 'w', encoding='utf-8') as f:
f.write(fixed)
これは単純な誤解釈の場合にのみ機能します。二重破損やエンコーディングの混在はより困難です。
ExcelにUTF-8を強制的に読ませる
ExcelはUTF-8を無視することがよくあります。2つの回避策:
方法1: BOMを追加
ファイル先頭のByte Order MarkがUTF-8を示します:
with open('file.csv', 'w', encoding='utf-8-sig') as f:
f.write(data)
方法2: インポートウィザード
CSVをダブルクリックする代わりに、データ → テキスト/CSVからインポートし、UTF-8エンコーディングを手動で指定します。
仲介としてのGoogleスプレッドシート
GoogleスプレッドシートはExcelよりエンコーディングを適切に処理します。CSVをそこにインポートし、XLSXとしてエクスポート。Excelファイルは文字を正しく保持します。
エンコーディング問題の予防
手動エクスポートの場合
エンコーディングを正しく処理するツールを使用してください。HTML Table Exporterはエクスポートプロセス全体でUnicodeを保持し、文字化けの原因となる変換エラーを回避します。
CSVエクスポートで、ツールがエンコーディングオプションを提供する場合、Excel互換性のためにUTF-8 with BOMを選択してください。
抽出ツールを構築する場合
エンコーディングは常に明示的に指定:
# CSV書き込み
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerows(data)
# HTML読み込み
response = requests.get(url)
response.encoding = response.apparent_encoding # 自動検出
html = response.text
JavaScript/ブラウザ拡張機能の場合:
// 明示的なエンコーディングを指定したBlob
const blob = new Blob(['\ufeff' + csvContent], {
type: 'text/csv;charset=utf-8;'
});
\ufeff はExcelを助けるBOMです。
Pandasを使用する場合
# 読み込み
df = pd.read_csv('file.csv', encoding='utf-8')
# Excel用BOM付きで書き込み
df.to_csv('output.csv', encoding='utf-8-sig', index=False)
問題を引き起こす特殊文字
スマートクォートとアポストロフィ
ワープロはストレートクォートをカーリークォートに変換します:
- ' → '(U+2019)
- " → " "(U+201C, U+201D)
これらはUTF-8ではマルチバイトであり、Latin-1で壊れます。
Emダッシュとenダッシュ
- —(emダッシュ、U+2014)
- –(enダッシュ、U+2013)
金融データや出版物で一般的です。
ノーブレークスペース
通常のスペースは 0x20。ノーブレークスペースは 0xA0(Latin-1)または 0xC2 0xA0(UTF-8)。
これらは不可視ですが、文字列比較とパースを壊します。
# スペースを正規化
text = text.replace('\xa0', ' ')
通貨記号
€、£、¥はすべてASCII外であり、UTF-8とLatin-1で異なるエンコーディングになります。
クイックリファレンス
| 問題 | 原因の可能性 | 修正方法 |
|---|---|---|
| Ãの後に文字 | UTF-8がLatin-1として読まれた | 再エンコードまたはインポート時にUTF-8指定 |
| ?や□が文字を置換 | エンコーディングが文字をサポートしない | 全工程でUTF-8を使用 |
| Excelで文字化け表示 | Excelがエンコーディングを誤推測 | UTF-8 BOMまたはインポートウィザード使用 |
| 不可視文字がデータを壊す | ノーブレークスペースやゼロ幅文字 | ホワイトスペースを正規化 |
基本原則
すべてのステップでエンコーディングを一致させること。 UTF-8でエクスポート。UTF-8で開く。UTF-8で保存。
一つのステップでも異なるエンコーディングを使った瞬間、文字が破損します。
迷ったら、Excelに触れるファイルにはUTF-8 with BOMが最も安全な選択です。
エンコーディングを正しく処理するエクスポートツールが欲しいですか?HTMLテーブルスクレイパー:Chrome拡張機能 トップ5もご参考に。詳しくは gauchogrid.com/ja/html-table-exporter をご覧いただくか、Chrome Web Store で無料でお試しください。
Top comments (0)